| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419 |
- unit TBXLists;
- // TBX Package
- // Copyright 2001-2004 Alex A. Denisov. All Rights Reserved
- // See TBX.chm for license and installation instructions
- //
- // Id: TBXLists.pas 7 2004-02-21 06:07:53Z
- interface
- {$I TB2Ver.inc}
- {$I TBX.inc}
- uses
- Windows, Messages, Classes, SysUtils, Controls, Forms, Graphics, TB2Item, TBX,
- TBXThemes, UxTheme, ImgList;
- type
- { TTBXScrollBar }
- TSBIncrement = 1..1000;
- TSBZone = (sbzEmpty, sbzPrev, sbzPagePrev, sbzHandle, sbzPageNext, sbzNext);
- TSBAutoScrollEvent = procedure(Sender: TObject; var Direction, Interval: Integer) of object;
- TTBXScrollBar = class
- private
- FBounds: TRect;
- FLeft: Integer;
- FHandle: HWND;
- FHeight: Integer;
- FIncrement: TSBIncrement;
- FKind: TScrollBarKind;
- FPosition: Integer;
- FRange: Integer;
- FRight: Integer;
- FTop: Integer;
- FWidth: Integer;
- FWindow: Integer;
- FOnChange: TNotifyEvent;
- FOnAutoScroll: TSBAutoScrollEvent;
- FOnRedrawRequest: TNotifyEvent;
- procedure SetBounds(const Value: TRect);
- procedure SetKind(Value: TScrollBarKind);
- procedure SetPosition(Value: Integer);
- procedure SetRange(Value: Integer);
- function GetHandle: HWND;
- protected
- AutoScrollDirection: Integer;
- AutoScrolling: Boolean;
- AutoScrollInterval: Integer;
- Zones: array [TSBZone] of TRect;
- MouseDownZone: TSBZone;
- MouseDownPoint: TPoint;
- MouseDownPosition: Integer;
- LastMousePoint: TPoint;
- PrevCapture: HWND;
- UserChange: Boolean;
- procedure AdjustPosition(var NewPosition: Integer);
- procedure CreateWnd;
- procedure DestroyWnd;
- function GetZone(X, Y: Integer): TSBZone;
- function GetEffectiveWindow: Integer;
- function GetEnabled: Boolean; virtual;
- procedure HandleZoneClick(AZone: TSBZone);
- procedure MouseDown(Button: TMouseButton; X, Y: Integer); virtual;
- procedure MouseMove(X, Y: Integer); virtual;
- procedure MouseUp(Button: TMouseButton; X, Y: Integer); virtual;
- procedure PaintButton(Canvas: TCanvas; Rect: TRect; Direction: Integer; Pushed, Enabled: Boolean);
- procedure PaintHandle(Canvas: TCanvas; Rect: TRect; Pushed, Enabled: Boolean);
- procedure PaintTrack(Canvas: TCanvas; Rect: TRect; IsNextZone, Pushed, Enabled: Boolean);
- procedure PaintTo(Canvas: TCanvas);
- procedure SBWndProc(var Message: TMessage);
- procedure StartAutoScroll(Direction, Interval: Integer);
- procedure StopAutoScroll;
- procedure StartTimer(ID: Integer; Elapse: Integer);
- procedure StopTimer(ID: Integer);
- procedure TimerElapsed(ID: Integer; var NewElapse: Integer); virtual;
- procedure UpdateZones;
- property Handle: HWND read GetHandle;
- public
- constructor Create;
- destructor Destroy; override;
- procedure Redraw; virtual;
- procedure UpdatePosition(NewPosition: Integer);
- property Kind: TScrollBarKind read FKind write SetKind;
- property Bounds: TRect read FBounds write SetBounds;
- property Left: Integer read FLeft;
- property Height: Integer read FHeight;
- property Increment: TSBIncrement read FIncrement write FIncrement;
- property Position: Integer read FPosition write SetPosition;
- property Range: Integer read FRange write SetRange;
- property Right: Integer read FRight;
- property Top: Integer read FTop;
- property Width: Integer read FWidth;
- property Window: Integer read FWindow write FWindow;
- property OnAutoScroll: TSBAutoScrollEvent read FOnAutoScroll write FOnAutoScroll;
- property OnChange: TNotifyEvent read FOnChange write FOnChange;
- property OnRedrawRequest: TNotifyEvent read FOnRedrawRequest write FOnRedrawRequest;
- end;
- { TTBXCustomList }
- TTBXCustomList = class;
- TTBXLMeasureHeight = procedure(Sender: TTBXCustomList; ACanvas: TCanvas; var AHeight: Integer) of object;
- TTBXLMeasureWidth = procedure(Sender: TTBXCustomList; ACanvas: TCanvas; AIndex: Integer; var AWidth: Integer) of object;
- TTBXLPaintEvent = procedure(Sender: TTBXCustomList; ACanvas: TCanvas; ARect: TRect; AIndex, AHoverIndex: Integer; var DrawDefault: Boolean) of object;
- TTBXLAdjustImageIndex = procedure(Sender: TTBXCustomList; AItemIndex: Integer; var ImageIndex: Integer) of object;
- TTBXCustomListViewer = class;
- TTBXCustomList = class(TTBXCustomItem)
- private
- FViewers: TList;
- FItemIndex: Integer;
- FMinWidth: Integer;
- FMaxWidth: Integer;
- FMaxVisibleItems: Integer;
- FShowImages: Boolean;
- FOnChange: TNotifyEvent;
- FOnClearItem: TTBXLPaintEvent;
- FOnDrawItem: TTBXLPaintEvent;
- FOnAdjustImageIndex: TTBXLAdjustImageIndex;
- FOnMeasureHeight: TTBXLMeasureHeight;
- FOnMeasureWidth: TTBXLMeasureWidth;
- procedure SetItemIndex(Value: Integer);
- protected
- function DoClearItem(ACanvas: TCanvas; ARect: TRect; AIndex, AHoverIndex: Integer): Boolean; virtual;
- function DoDrawItem(ACanvas: TCanvas; {MP} var ARect: TRect; AIndex, AHoverIndex: Integer): Boolean; virtual;
- procedure DoMeasureHeight(ACanvas: TCanvas; var AHeight: Integer); virtual;
- procedure DoMeasureWidth(ACanvas: TCanvas; AIndex: Integer; var AWidth: Integer); virtual;
- procedure DrawItem(ACanvas: TCanvas; AViewer: TTBXCustomListViewer; const ARect: TRect; AIndex, AHoverIndex: Integer); virtual;
- function GetImageIndex(ItemIndex: Integer): Integer; virtual;
- function GetItemViewerClass(AView: TTBView): TTBItemViewerClass; override;
- function GetItemText(Index: Integer): string; virtual; abstract;
- function GetCount: Integer; virtual; abstract;
- procedure HandleChange; virtual;
- procedure HandleHover(AIndex: Integer); virtual;
- procedure Notification(AComponent: TComponent; Operation: TOperation); override;
- public
- constructor Create(AOwner: TComponent); override;
- procedure MakeVisible(AIndex: Integer);
- property ItemIndex: Integer read FItemIndex write SetItemIndex default -1;
- property MaxVisibleItems: Integer read FMaxVisibleItems write FMaxVisibleItems default 8;
- property MaxWidth: Integer read FMaxWidth write FMaxWidth default 0;
- property MinWidth: Integer read FMinWidth write FMinWidth default 32;
- property ShowImages: Boolean read FShowImages write FShowImages default False;
- property OnAdjustImageIndex: TTBXLAdjustImageIndex read FOnAdjustImageIndex write FOnAdjustImageIndex;
- property OnChange: TNotifyEvent read FOnChange write FOnChange;
- property OnClearItem: TTBXLPaintEvent read FOnClearItem write FOnClearItem;
- property OnDrawItem: TTBXLPaintEvent read FOnDrawItem write FOnDrawItem;
- property OnMeasureHeight: TTBXLMeasureHeight read FOnMeasureHeight write FOnMeasureHeight;
- property OnMeasureWidth: TTBXLMeasureWidth read FOnMeasureWidth write FOnMeasureWidth;
- end;
- TTBXCustomListViewer = class(TTBXItemViewer)
- private
- FItemCount: Integer;
- FItemHeight: Integer;
- FHoverIndex: Integer;
- FHeight: Integer;
- FLastClientRect: TRect;
- FWheelAccumulator: Integer;
- FWidth: Integer;
- FOffset: Integer;
- FScrollBarWidth: Integer;
- FScrollBar: TTBXScrollBar;
- FVisibleItems: Integer;
- procedure ListChangeHandler(NewIndex: Integer);
- procedure SBAutoScrollHandler(Sender: TObject; var Direction, Interval: Integer);
- procedure SBChangeHandler(Sender: TObject);
- procedure SBRedrawHandler(Sender: TObject);
- protected
- MouseIsDown: Boolean;
- MouseInScrollBar: Boolean;
- IgnoreMouseUp: Boolean;
- IsChanging: Boolean;
- procedure AdjustAutoScrollHover(var AIndex: Integer; Direction: Integer); virtual;
- procedure CalcSize(const Canvas: TCanvas; var AWidth, AHeight: Integer); override;
- procedure DrawItems(const Canvas: TCanvas; const ClientAreaRect: TRect);
- function GetItemIndexAt(X, Y: Integer): Integer;
- function GetItemRect(Index: Integer): TRect;
- function GetItemHeight(ACanvas: TCanvas): Integer; virtual;
- function GetItemWidth(ACanvas: TCanvas; Index: Integer): Integer; virtual;
- procedure HandleAutoScroll(var Direction, Interval: Integer); virtual;
- procedure KeyDown(var Key: Word; Shift: TShiftState); override;
- procedure MakeVisible(Index: Integer);
- procedure MouseDown(Shift: TShiftState; X, Y: Integer; var MouseDownOnMenu: Boolean); override;
- procedure MouseMove(X, Y: Integer); override;
- procedure MouseUp(X, Y: Integer; MouseWasDownOnMenu: Boolean); override;
- procedure MouseWheel(WheelDelta: Integer; X, Y: Integer); override;
- procedure Paint(const Canvas: TCanvas; const ClientAreaRect: TRect; IsHoverItem, IsPushed, UseDisabledShadow: Boolean); override;
- procedure UpdateItems;
- property HoverIndex: Integer read FHoverIndex write FHoverIndex;
- property Offset: Integer read FOffset; {vb+}
- property VisibleItems: Integer read FVisibleItems; {vb+}
- public
- constructor Create(AView: TTBView; AItem: TTBCustomItem; AGroupLevel: Integer); override;
- destructor Destroy; override;
- end;
- { TTBXStringList }
- TTBXStringList = class(TTBXCustomList)
- private
- FStrings: TStrings;
- procedure SetStrings(Value: TStrings);
- protected
- function GetItemText(Index: Integer): string; override;
- function GetCount: Integer; override;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- published
- property ItemIndex;
- property MaxVisibleItems;
- property MaxWidth;
- property MinWidth;
- property Strings: TStrings read FStrings write SetStrings;
- property OnAdjustImageIndex;
- property OnChange;
- property OnClearItem;
- property OnClick;
- property OnDrawItem;
- property OnMeasureHeight;
- property OnMeasureWidth;
- end;
- TTBXStringListClass = class of TTBXStringList;
- {$IFNDEF MPEXCLUDE}
- { TTBXUndoList }
- TTBXUndoList = class(TTBXStringList)
- protected
- procedure DrawItem(ACanvas: TCanvas; AViewer: TTBXCustomListViewer; const ARect: TRect; AIndex, AHoverIndex: Integer); override;
- function GetItemViewerClass(AView: TTBView): TTBItemViewerClass; override;
- procedure HandleHover(AIndex: Integer); override;
- end;
- TTBXUndoListViewer = class(TTBXCustomListViewer)
- protected
- procedure AdjustAutoScrollHover(var AIndex: Integer; Direction: Integer); override;
- procedure HandleAutoScroll(var Direction, Interval: Integer); override;
- end;
- {$ENDIF}
- implementation
- uses Types;
- type TTBViewAccess = class(TTBView);
- const
- SCROLL_TIMER = 1;
- AUTO_SCROLL_TIMER = 2;
- MIN_SB_HANDLE_SIZE = 8;
- CImageSpacing = 4;
- //----------------------------------------------------------------------------//
- { TTBXScrollBar }
- procedure TTBXScrollBar.AdjustPosition(var NewPosition: Integer);
- var
- W: Integer;
- begin
- W := GetEffectiveWindow;
- if NewPosition + W > Range then NewPosition := Range - W;
- if NewPosition < 0 then NewPosition := 0;
- end;
- constructor TTBXScrollBar.Create;
- begin
- FIncrement := 1;
- end;
- procedure TTBXScrollBar.CreateWnd;
- begin
- if FHandle = 0 then FHandle := {$IFDEF JR_D6}Classes.{$ENDIF}AllocateHWnd(SBWndProc);
- end;
- destructor TTBXScrollBar.Destroy;
- begin
- DestroyWnd;
- inherited;
- end;
- procedure TTBXScrollBar.DestroyWnd;
- begin
- if FHandle <> 0 then
- begin
- {$IFDEF JR_D6}Classes.{$ENDIF}DeallocateHWnd(FHandle);
- FHandle := 0;
- end;
- end;
- function TTBXScrollBar.GetEffectiveWindow: Integer;
- begin
- if Window <= 0 then
- begin
- if Kind = sbVertical then Result := Height
- else Result := Width;
- end
- else Result := Window;
- end;
- function TTBXScrollBar.GetEnabled: Boolean;
- begin
- Result := Range > GetEffectiveWindow;
- end;
- function TTBXScrollBar.GetHandle: HWND;
- begin
- if FHandle = 0 then CreateWnd;
- Result := FHandle;
- end;
- function TTBXScrollBar.GetZone(X, Y: Integer): TSBZone;
- var
- I: Integer;
- Pt: TPoint;
- begin
- Pt.X := X;
- Pt.Y := Y;
- for I := Ord(sbzPrev) to Ord(sbzNext) do
- begin
- Result := TSBZone(I);
- if PtInRect(Zones[Result], Pt) then Exit;
- end;
- Result := sbzEmpty;
- end;
- procedure TTBXScrollBar.HandleZoneClick(AZone: TSBZone);
- begin
- UserChange := True;
- case AZone of
- sbzPrev: Position := Position - Increment;
- sbzPagePrev: Position := Position - GetEffectiveWindow;
- sbzPageNext: Position := Position + GetEffectiveWindow;
- sbzNext: Position := Position + Increment;
- end;
- UserChange := False;
- end;
- procedure TTBXScrollBar.MouseDown(Button: TMouseButton; X, Y: Integer);
- begin
- if Button = mbLeft then
- begin
- MouseDownZone := GetZone(X, Y);
- MouseDownPoint := Point(X, Y);
- MouseDownPosition := Position;
- LastMousePoint := MouseDownPoint;
- if MouseDownZone in [sbzPrev, sbzPagePrev, sbzPageNext, sbzNext] then
- begin
- HandleZoneClick(MouseDownZone);
- StartTimer(SCROLL_TIMER, 500);
- end;
- Redraw;
- end;
- end;
- procedure TTBXScrollBar.MouseMove(X, Y: Integer);
- var
- Delta: Integer;
- ClientSize, HandleSize: Integer;
- begin
- LastMousePoint := Point(X, Y);
- if MouseDownZone = sbzHandle then
- begin
- if Kind = sbVertical then
- begin
- Delta := Y - MouseDownPoint.Y;
- ClientSize := Zones[sbzPageNext].Bottom - Zones[sbzPagePrev].Top;
- end
- else
- begin
- Delta := X - MouseDownPoint.X;
- ClientSize := Zones[sbzPageNext].Right - Zones[sbzPagePrev].Left;
- end;
- HandleSize := Round(ClientSize * Window / Range);
- if HandleSize < MIN_SB_HANDLE_SIZE then
- Delta := Round(Delta * (Range - Window) / (ClientSize - MIN_SB_HANDLE_SIZE))
- else
- Delta := Round(Delta * Range / ClientSize);
- if MouseDownPosition + Delta <> Position then
- begin
- UserChange := True;
- Position := MouseDownPosition + Delta;
- UserChange := False;
- end;
- end;
- end;
- procedure TTBXScrollBar.MouseUp(Button: TMouseButton; X, Y: Integer);
- begin
- StopTimer(SCROLL_TIMER);
- if Button = mbLeft then
- begin
- MouseDownZone := sbzEmpty;
- Redraw;
- end;
- end;
- procedure TTBXScrollBar.PaintButton(Canvas: TCanvas; Rect: TRect;
- Direction: Integer; Pushed, Enabled: Boolean);
- const
- DirectionFlags: array [0..3] of Cardinal = (DFCS_SCROLLLEFT, DFCS_SCROLLUP,
- DFCS_SCROLLRIGHT, DFCS_SCROLLDOWN);
- EnabledFlags: array [Boolean] of Cardinal = (DFCS_INACTIVE, 0);
- PushedFlags: array [Boolean] of Cardinal = (0, DFCS_PUSHED or DFCS_FLAT);
- DirectionXPFlags: array [0..3] of Cardinal = (ABS_LEFTNORMAL, ABS_UPNORMAL,
- ABS_RIGHTNORMAL, ABS_DOWNNORMAL);
- var
- StateFlags: Cardinal;
- begin
- if USE_THEMES then
- begin
- StateFlags := DirectionXPFlags[Direction];
- if not Enabled then Inc(StateFlags, 3)
- else if Pushed then Inc(StateFlags, 2);
- DrawThemeBackground(SCROLLBAR_THEME, Canvas.Handle, SBP_ARROWBTN, StateFlags, Rect, nil);
- end
- else
- begin
- DrawFrameControl(Canvas.Handle, Rect, DFC_SCROLL,
- DirectionFlags[Direction] or EnabledFlags[Enabled] or PushedFlags[Pushed]);
- end;
- end;
- procedure TTBXScrollBar.PaintHandle(Canvas: TCanvas; Rect: TRect; Pushed, Enabled: Boolean);
- const
- PartXPFlags: array [TScrollBarKind] of Cardinal = (SBP_THUMBBTNHORZ, SBP_THUMBBTNVERT);
- var
- StateFlags: Cardinal;
- begin
- if USE_THEMES then
- begin
- StateFlags := SCRBS_NORMAL;
- if not Enabled then Inc(StateFlags, 3)
- else if Pushed then Inc(StateFlags, 2);
- DrawThemeBackground(SCROLLBAR_THEME, Canvas.Handle, PartXPFlags[Kind], StateFlags, Rect, nil);
- end
- else
- begin
- DrawEdge(Canvas.Handle, Rect, EDGE_RAISED, BF_RECT or BF_ADJUST);
- Canvas.Brush.Color := clBtnFace;
- Canvas.FillRect(Rect);
- end;
- end;
- procedure TTBXScrollBar.PaintTo(Canvas: TCanvas);
- var
- R: TRect;
- E, IsVert: Boolean;
- I: Integer;
- Dummy: TPoint;
- begin
- UpdateZones;
- IsVert := Kind = sbVertical;
- E := GetEnabled;
- OffsetWindowOrgEx(Canvas.Handle, -Bounds.Left, -Bounds.Top, Dummy);
- try
- if IsVert then I := 1 else I := 0;
- PaintButton(Canvas, Zones[sbzPrev], I, MouseDownZone = sbzPrev, E);
- PaintButton(Canvas, Zones[sbzNext], I + 2, MouseDownZone = sbzNext, E);
- if not IsRectEmpty(Zones[sbzEmpty]) then
- begin
- Canvas.Brush.Color := clScrollBar;
- Canvas.Brush.Style := bsSolid;
- Canvas.FillRect(Zones[sbzEmpty]);
- end;
- if not IsRectEmpty(Zones[sbzPagePrev]) or not IsRectEmpty(Zones[sbzPageNext]) then
- begin
- R := Zones[sbzPagePrev];
- PaintTrack(Canvas, R, False, MouseDownZone = sbzPagePrev, E);
- R := Zones[sbzPageNext];
- PaintTrack(Canvas, R, True, MouseDownZone = sbzPageNext, E);
- end;
- if not IsRectEmpty(Zones[sbzHandle]) then
- PaintHandle(Canvas, Zones[sbzHandle], MouseDownZone = sbzHandle, E);
- finally
- OffsetWindowOrgEx(Canvas.Handle, Bounds.Left, Bounds.Top, Dummy);
- end;
- end;
- procedure TTBXScrollBar.PaintTrack(Canvas: TCanvas; Rect: TRect;
- IsNextZone, Pushed, Enabled: Boolean);
- const
- PartXPFlags: array [Boolean, TScrollBarKind] of Cardinal =
- ((SBP_LOWERTRACKHORZ, SBP_LOWERTRACKVERT), (SBP_UPPERTRACKHORZ, SBP_UPPERTRACKVERT));
- var
- StateFlags: Cardinal;
- begin
- if USE_THEMES then
- begin
- StateFlags := SCRBS_NORMAL;
- if not Enabled then Inc(StateFlags, 3)
- else if Pushed then Inc(StateFlags, 2);
- DrawThemeBackground(SCROLLBAR_THEME, Canvas.Handle, PartXPFlags[IsNextZone, Kind],
- StateFlags, Rect, nil);
- end
- else
- begin
- if Pushed then Canvas.Brush.Color := cl3DDkShadow
- else Canvas.Brush.Bitmap := AllocPatternBitmap(clBtnHighlight, clScrollBar);
- Canvas.FillRect(Rect);
- end;
- end;
- procedure TTBXScrollBar.Redraw;
- begin
- if Assigned(FOnRedrawRequest) then FOnRedrawRequest(Self);
- end;
- procedure TTBXScrollBar.SBWndProc(var Message: TMessage);
- var
- I: Integer;
- procedure DefaultHandler;
- begin
- with Message do
- Result := DefWindowProc(FHandle, Msg, wParam, lParam);
- end;
- begin
- case Message.Msg of
- WM_TIMER: with TWMTimer(Message) do
- begin
- I := 0;
- TimerElapsed(TimerID, I);
- if I > 0 then StartTimer(TimerID, I)
- else StopTimer(TimerID);
- Result := 0;
- end;
- else
- DefaultHandler;
- end;
- end;
- procedure TTBXScrollBar.SetBounds(const Value: TRect);
- begin
- FBounds := Value;
- with Value do
- begin
- FLeft := Left;
- FTop := Top;
- FWidth := Right - Left;
- FHeight := Bottom - Top;
- end;
- UpdateZones;
- end;
- procedure TTBXScrollBar.SetKind(Value: TScrollBarKind);
- begin
- FKind := Value;
- UpdateZones;
- end;
- procedure TTBXScrollBar.SetPosition(Value: Integer);
- begin
- AdjustPosition(Value);
- if Value <> FPosition then
- begin
- FPosition := Value;
- if UserChange then
- begin
- Redraw;
- if Assigned(FOnChange) then FOnChange(Self);
- end;
- end;
- end;
- procedure TTBXScrollBar.SetRange(Value: Integer);
- begin
- if Value < 0 then Value := 0;
- if Value <> FRange then
- begin
- FRange := Value;
- Redraw;
- SetPosition(Position);
- end;
- end;
- procedure TTBXScrollBar.StartAutoScroll(Direction, Interval: Integer);
- begin
- if Direction <> 0 then
- begin
- AutoScrollDirection := Direction;
- AutoScrollInterval := Interval;
- if not AutoScrolling then
- begin
- StartTimer(AUTO_SCROLL_TIMER, Interval);
- AutoScrolling := True;
- end;
- end;
- end;
- procedure TTBXScrollBar.StartTimer(ID, Elapse: Integer);
- begin
- SetTimer(Handle, ID, Elapse, nil);
- end;
- procedure TTBXScrollBar.StopAutoScroll;
- begin
- if AutoScrolling then
- begin
- AutoScrolling := False;
- StopTimer(AUTO_SCROLL_TIMER);
- end;
- end;
- procedure TTBXScrollBar.StopTimer(ID: Integer);
- begin
- KillTimer(Handle, ID);
- end;
- procedure TTBXScrollBar.TimerElapsed(ID: Integer; var NewElapse: Integer);
- begin
- case ID of
- SCROLL_TIMER:
- if MouseDownZone <> sbzEmpty then
- if not (MouseDownZone in [sbzPagePrev, sbzPageNext]) or
- (GetZone(LastMousePoint.X, LastMousePoint.Y) = MouseDownZone) then
- begin
- HandleZoneClick(MouseDownZone);
- NewElapse := 100;
- end;
- AUTO_SCROLL_TIMER: if AutoScrolling then
- begin
- NewElapse := AutoScrollInterval;
- UpdatePosition(Position + AutoScrollDirection);
- if (Position = 0) or (Position + Window = Range) then NewElapse := 0;
- if Assigned(FOnAutoScroll) then
- FOnAutoScroll(Self, AutoScrollDirection, AutoScrollInterval);
- AutoScrolling := NewElapse > 0;
- end;
- end;
- end;
- procedure TTBXScrollBar.UpdatePosition(NewPosition: Integer);
- begin
- UserChange := True;
- if NewPosition < 0 then NewPosition := 0;
- if NewPosition > Range - Window then NewPosition := Range - Window;
- Position := NewPosition;
- UserChange := False;
- end;
- procedure TTBXScrollBar.UpdateZones;
- var
- SzL, SzT: Integer;
- ButtonSize: Integer;
- Lo, Hi: Integer;
- HandleSize, HandlePos: Integer;
- Window: Integer;
- IsVert: Boolean;
- procedure SetZone(var R: TRect; Lo, Hi: Integer);
- begin
- if IsVert then
- begin
- R.Left := 0;
- R.Right := Width;
- R.Top := Lo;
- R.Bottom := Hi;
- end
- else
- begin
- R.Left := Lo;
- R.Right := Hi;
- R.Top := 0;
- R.Bottom := Height;
- end;
- end;
- begin
- IsVert := Kind = sbVertical;
- Window := GetEffectiveWindow;
- if IsVert then
- begin
- SzL := Height;
- SzT := Width;
- end
- else
- begin
- SzL := Width;
- SzT := Height;
- end;
- { Buttons }
- ButtonSize := SzT;
- if ButtonSize * 2 >= SzL - 2 then ButtonSize := (SzL - 2) div 2;
- SetZone(Zones[sbzPrev], 0, ButtonSize);
- SetZone(Zones[sbzNext], SzL - ButtonSize, SzL);
- { Handle }
- Lo := ButtonSize;
- Hi := SzL - ButtonSize;
- if GetEnabled and (Hi - Lo > MIN_SB_HANDLE_SIZE + 4) then
- begin
- HandleSize := Round((Hi - Lo) * Window / Range);
- if HandleSize >= MIN_SB_HANDLE_SIZE then
- HandlePos := Round((Hi - Lo) * Position / Range)
- else
- begin
- HandleSize := MIN_SB_HANDLE_SIZE;
- HandlePos := Round((Hi - Lo - MIN_SB_HANDLE_SIZE) * Position / (Range - Window));
- end;
- Inc(HandlePos, Lo);
- SetZone(Zones[sbzHandle], HandlePos, HandlePos + HandleSize);
- SetZone(Zones[sbzPagePrev], Lo, HandlePos);
- SetZone(Zones[sbzPageNext], HandlePos + HandleSize, Hi);
- Zones[sbzEmpty].Right := -1;
- end
- else
- begin
- { Invalidate invisible zones }
- Zones[sbzPagePrev].Right := -1;
- Zones[sbzHandle].Right := -1;
- Zones[sbzPageNext].Right := -1;
- SetZone(Zones[sbzEmpty], Lo, Hi);
- end;
- end;
- //----------------------------------------------------------------------------//
- { TTBXCustomList }
- constructor TTBXCustomList.Create(AOwner: TComponent);
- begin
- inherited;
- FMinWidth := 32;
- FMaxWidth := 0;
- FMaxVisibleItems := 8;
- FItemIndex := -1;
- end;
- function TTBXCustomList.DoClearItem(ACanvas: TCanvas; ARect: TRect; AIndex, AHoverIndex: Integer): Boolean;
- begin
- Result := True;
- if Assigned(FOnClearItem) then FOnClearItem(Self, ACanvas, ARect, AIndex, AHoverIndex, Result);
- end;
- function TTBXCustomList.DoDrawItem(ACanvas: TCanvas; {MP} var ARect: TRect; AIndex, AHoverIndex: Integer): Boolean;
- begin
- Result := True;
- if Assigned(FOnDrawItem) then FOnDrawItem(Self, ACanvas, ARect, AIndex, AHoverIndex, Result);
- end;
- procedure TTBXCustomList.DoMeasureHeight(ACanvas: TCanvas; var AHeight: Integer);
- begin
- if Assigned(FOnMeasureHeight) then FOnMeasureHeight(Self, ACanvas, AHeight);
- end;
- procedure TTBXCustomList.DoMeasureWidth(ACanvas: TCanvas; AIndex: Integer; var AWidth: Integer);
- begin
- if Assigned(FOnMeasureWidth) then FOnMeasureWidth(Self, ACanvas, AIndex, AWidth);
- end;
- procedure TTBXCustomList.DrawItem(ACanvas: TCanvas; AViewer: TTBXCustomListViewer;
- const ARect: TRect; AIndex, AHoverIndex: Integer);
- const
- FillColors: array [Boolean] of TColor = (clWindow, clHighlight);
- TextColors: array [Boolean] of TColor = (clWindowText, clHighlightText);
- var
- S: string;
- R, R2: TRect;
- ImgList: TCustomImageList;
- begin
- ACanvas.Brush.Color := FillColors[AIndex = AHoverIndex];
- if DoClearItem(ACanvas, ARect, AIndex, AHoverIndex) then ACanvas.FillRect(ARect);
- ACanvas.Font.Color := TextColors[AIndex = AHoverIndex];
- R := ARect; {MP}
- if DoDrawItem(ACanvas, {MP} R, AIndex, AHoverIndex) then
- begin
- InflateRect(R, -4, 1);
- ImgList := AViewer.GetImageList;
- if ShowImages and (ImgList <> nil) then
- begin
- R2.Left := R.Left;
- R2.Top := (R.Top + R.Bottom - ImgList.Height) div 2;
- R2.Right := R2.Left + ImgList.Width;
- R2.Bottom := R2.Top + ImgList.Height;
- if Enabled then ImgList.Draw(ACanvas, R2.Left, R2.Top, GetImageIndex(AIndex))
- else DrawTBXImage(ACanvas, R2, ImgList, GetImageIndex(AIndex), ISF_DISABLED);
- Inc(R.Left, ImgList.Width + CImageSpacing);
- end;
- S := GetItemText(AIndex);
- if Length(S) > 0 then
- begin
- ACanvas.Brush.Style := bsClear;
- DrawText(ACanvas.Handle, PChar(S), Length(S), R, DT_SINGLELINE or DT_VCENTER {MP DEL});
- ACanvas.Brush.Style := bsSolid;
- end;
- end;
- end;
- function TTBXCustomList.GetImageIndex(ItemIndex: Integer): Integer;
- begin
- Result := ItemIndex;
- if Assigned(FOnAdjustImageIndex) then FOnAdjustImageIndex(Self, ItemIndex, Result);
- end;
- function TTBXCustomList.GetItemViewerClass(AView: TTBView): TTBItemViewerClass;
- begin
- Result := TTBXCustomListViewer;
- end;
- procedure TTBXCustomList.HandleChange;
- begin
- if Assigned(FOnChange) then FOnChange(Self);
- end;
- procedure TTBXCustomList.HandleHover(AIndex: Integer);
- begin
- end;
- procedure TTBXCustomList.MakeVisible(AIndex: Integer);
- var
- I: Integer;
- begin
- if FViewers <> nil then
- for I := 0 to FViewers.Count - 1 do
- TTBXCustomListViewer(FViewers[I]).MakeVisible(AIndex);
- end;
- procedure TTBXCustomList.Notification(AComponent: TComponent; Operation: TOperation);
- begin
- inherited Notification(AComponent, Operation);
- if (Operation = opRemove) and (AComponent = Images) then Images := nil;
- end;
- procedure TTBXCustomList.SetItemIndex(Value: Integer);
- var
- I: Integer;
- begin
- if Value < 0 then Value := -1;
- FItemIndex := Value;
- { Update viewers }
- if FViewers <> nil then
- for I := 0 to FViewers.Count - 1 do
- TTBXCustomListViewer(FViewers[I]).ListChangeHandler(Value);
- if Assigned(FOnChange) then FOnChange(Self);
- end;
- //----------------------------------------------------------------------------//
- { TTBXCustomListViewer }
- procedure TTBXCustomListViewer.AdjustAutoScrollHover(var AIndex: Integer; Direction: Integer);
- begin
- AIndex := -1; // turn off hover when autoscrolling
- end;
- procedure TTBXCustomListViewer.CalcSize(const Canvas: TCanvas; var AWidth, AHeight: Integer);
- var
- Item: TTBXCustomList;
- I, W: Integer;
- begin
- Item := TTBXCustomList(Self.Item);
- Canvas.Font := TTBViewAccess(View).GetFont;
- FItemCount := Item.GetCount;
- FItemHeight := GetItemHeight(Canvas);
- FVisibleItems := FItemCount;
- if FVisibleItems > Item.MaxVisibleItems then FVisibleItems := Item.MaxVisibleItems
- else if FVisibleItems <= 0 then FVisibleItems := 1;
- AHeight := FVisibleItems * FItemHeight;
- AWidth := 0;
- for I := 0 to FItemCount - 1 do
- begin
- W := GetItemWidth(Canvas, I);
- if W > AWidth then AWidth := W;
- end;
- if FItemCount > FVisibleItems then FScrollBarWidth := GetSystemMetrics(SM_CXVSCROLL)
- else FScrollBarWidth := 0;
- Inc(AWidth, FScrollBarWidth);
- if AWidth < Item.MinWidth then AWidth := Item.MinWidth;
- if (Item.MaxWidth > Item.MinWidth) and (AWidth > Item.MaxWidth) then AWidth := Item.MaxWidth;
- end;
- constructor TTBXCustomListViewer.Create(AView: TTBView; AItem: TTBCustomItem; AGroupLevel: Integer);
- var
- Index: Integer;
- begin
- inherited;
- Index := TTBXCustomList(AItem).ItemIndex;
- FItemCount := TTBXCustomList(AItem).GetCount;
- if (Index >= 0) and (Index < FItemCount) then
- with TTBXCustomList(AItem) do
- begin
- FVisibleItems := GetCount;
- if FVisibleItems > MaxVisibleItems then FVisibleItems := MaxVisibleItems;
- if Index < FOffset then FOffset := Index
- else if Index >= FOffset + FVisibleItems then FOffset := Index - FVisibleItems + 1
- end;
- FHoverIndex := Index;
- if FHoverIndex > FItemCount then FHoverIndex := -1;
- AddToList(TTBXCustomList(AItem).FViewers, Self);
- end;
- destructor TTBXCustomListViewer.Destroy;
- begin
- RemoveFromList(TTBXCustomList(Item).FViewers, Self);
- if FScrollBar <> nil then FScrollBar.Free;
- inherited;
- end;
- procedure TTBXCustomListViewer.DrawItems(const Canvas: TCanvas; const ClientAreaRect: TRect);
- var
- I: Integer;
- R: TRect;
- begin
- R := ClientAreaRect;
- R.Bottom := FItemHeight;
- Dec(R.Right, FScrollBarWidth);
- Canvas.Font := TTBViewAccess(View).GetFont;
- for I := FOffset to FItemCount - 1 do
- begin
- if RectVisible(Canvas.Handle, R) then
- TTBXCustomList(Item).DrawItem(Canvas, Self, R, I, HoverIndex);
- R.Top := R.Bottom;
- Inc(R.Bottom, FItemHeight);
- if R.Bottom > FHeight then Break;
- end;
- if R.Top < ClientAreaRect.Bottom then
- begin
- R.Bottom := ClientAreaRect.Bottom;
- Canvas.Brush.Color := clWindow;
- Canvas.FillRect(R);
- end;
- end;
- function TTBXCustomListViewer.GetItemHeight(ACanvas: TCanvas): Integer;
- var
- ImgList: TCustomImageList;
- begin
- Result := ACanvas.TextHeight('Q') + 2;
- with TTBXStringList(Item) do
- begin
- ImgList := GetImageList;
- if ShowImages and (ImgList <> nil) and (Result < ImgList.Height + 2) then
- Result := ImgList.Height + 2;
- DoMeasureHeight(ACanvas, Result);
- end;
- end;
- function TTBXCustomListViewer.GetItemIndexAt(X, Y: Integer): Integer;
- begin
- if (X < 0) or (X > FWidth - FScrollBarWidth) then Result := -1
- else
- begin
- Result := (Y div FItemHeight) + FOffset;
- if (Result < FOffset) or (Result >= FOffset + FVisibleItems) or (Result >= FItemCount) then
- Result := - 1;
- end;
- end;
- function TTBXCustomListViewer.GetItemRect(Index: Integer): TRect;
- begin
- { Note this method works properly only after Draw is called }
- Result := FLastClientRect;
- Inc(Result.Top, (Index - FOffset) * FItemHeight);
- Result.Bottom := Result.Top + FItemHeight;
- Dec(Result.Right, FScrollBarWidth);
- end;
- function TTBXCustomListViewer.GetItemWidth(ACanvas: TCanvas; Index: Integer): Integer;
- var
- S: string;
- ImgList: TCustomImageList;
- begin
- with TTBXStringList(Item) do
- begin
- S := GetItemText(Index);
- Result := ACanvas.TextWidth(S);
- if ShowImages then
- begin
- ImgList := GetImageList;
- if ImgList <> nil then
- begin
- Inc(Result, ImgList.Width);
- if Length(S) > 0 then Inc(Result, CImageSpacing);
- end;
- end;
- Inc(Result, 8);
- DoMeasureWidth(ACanvas, Index, Result)
- end;
- end;
- procedure TTBXCustomListViewer.HandleAutoScroll(var Direction, Interval: Integer);
- begin
- // do nothing by default
- end;
- procedure TTBXCustomListViewer.KeyDown(var Key: Word; Shift: TShiftState);
- var
- OldIndex, NewIndex, Index: Integer;
- DAD: TTBDoneActionData;
- begin
- OldIndex := FHoverIndex;
- case Key of
- VK_UP: NewIndex := OldIndex - 1;
- VK_DOWN: NewIndex := OldIndex + 1;
- VK_PRIOR: NewIndex := OldIndex - FVisibleItems;
- VK_NEXT: NewIndex := OldIndex + FVisibleItems;
- VK_HOME: NewIndex := 0;
- VK_END: NewIndex := FItemCount - 1;
- VK_RETURN:
- begin
- TTBXCustomList(Item).ItemIndex := FHoverIndex;
- Exit;
- end;
- {MP}
- Word('A')..Word('Z'), Word('a')..Word('z'):
- begin
- NewIndex := OldIndex;
- for Index := FHoverIndex + 1 to FHoverIndex + FItemCount do
- begin
- if IsAccel(Key, TTBXStringList(Item).GetItemText(Index mod FItemCount)) then
- begin
- NewIndex := Index mod FItemCount;
- // exit modal loop
- DAD := TTBViewAccess(TTBViewAccess(View).GetRootView).DoneActionData;
- DAD.ClickItem := Item;
- DAD.DoneAction := tbdaClickItem;
- DAD.Sound := True;
- TTBViewAccess(TTBViewAccess(View).GetRootView).DoneActionData := DAD;
- Break;
- end;
- end;
- Key := 0;
- end;
- else
- Exit;
- end;
- Key := 0;
- if NewIndex < 0 then NewIndex := 0;
- if NewIndex >= FItemCount then NewIndex := FItemCount - 1;
- TTBXCustomList(Item).ItemIndex := NewIndex;
- end;
- procedure TTBXCustomListViewer.ListChangeHandler(NewIndex: Integer);
- begin
- if not IsChanging and (NewIndex <> HoverIndex) then
- begin
- IsChanging := True;
- HoverIndex := NewIndex;
- TTBXCustomList(Item).HandleHover(NewIndex);
- MakeVisible(HoverIndex);
- UpdateItems;
- IsChanging := False;
- end;
- end;
- procedure TTBXCustomListViewer.MakeVisible(Index: Integer);
- begin
- if (Index >= 0) and (Index < FItemCount) then
- begin
- if Index < FOffset then FScrollBar.UpdatePosition(Index)
- else if Index >= FOffset + FVisibleItems then FScrollBar.UpdatePosition(Index - FVisibleItems + 1);
- end;
- end;
- procedure TTBXCustomListViewer.MouseDown(Shift: TShiftState; X, Y: Integer; var MouseDownOnMenu: Boolean);
- begin
- if X > FWidth - FScrollBarWidth then
- begin
- Dec(X, FWidth - FScrollBarWidth);
- MouseInScrollBar := True;
- FScrollBar.MouseDown(mbLeft, X, Y);
- MouseDownOnMenu := False;
- end
- else
- begin
- MouseIsDown := True;
- MouseMove(X, Y);
- end;
- inherited;
- View.SetCapture;
- end;
- procedure TTBXCustomListViewer.MouseMove(X, Y: Integer);
- var
- NewHoverIndex, OldHoverIndex, IndexLo, IndexHi, I: Integer;
- R: TRect;
- Canvas: TCanvas;
- DC: HDC;
- V, Dir: Integer;
- begin
- if MouseInScrollBar then
- begin
- Dec(X, FWidth - FScrollBarWidth);
- FScrollBar.MouseMove(X, Y);
- Exit;
- end;
- if not View.Capture and (GetKeyState(VK_LBUTTON) < 0) then
- begin
- View.SetCapture;
- MouseIsDown := True;
- end;
- NewHoverIndex := GetItemIndexAt(X, Y);
- if FScrollBar <> nil then
- begin
- if MouseIsDown and ((Y < 0) or (Y >= FHeight)) then
- begin
- { Get AutoScroll Intervals }
- V := Y;
- if V >= FHeight then Dec(V, FHeight - 1);
- V := Abs(V);
- if Y < 0 then Dir := -1 else Dir := 1;
- case V of
- 0..9: V := 150;
- 10..29: V := 100;
- 30..50: begin V := 100; Dir := Dir * 2; end;
- else
- V := 100;
- Dir := Dir * 4;
- end;
- if ((Dir < 0) and (FOffset > 0)) or
- ((Dir > 0) and (FOffset + FVisibleItems < FItemCount)) then
- FScrollBar.StartAutoScroll(Dir, V)
- else
- FScrollBar.StopAutoScroll;
- AdjustAutoScrollHover(NewHoverIndex, Dir);
- end
- else FScrollBar.StopAutoScroll;
- end;
- if not MouseIsDown and (NewHoverIndex = -1) then Exit;
- if NewHoverIndex <> FHoverIndex then
- begin
- Canvas := TCanvas.Create;
- DC := GetDC(View.Window.Handle);
- OldHoverIndex := FHoverIndex;
- FHoverIndex := NewHoverIndex;
- try
- SetWindowOrgEx(DC, -BoundsRect.Left, -BoundsRect.Top, nil);
- Canvas.Handle := DC;
- Canvas.Font := TTBViewAccess(View).GetFont;
- IndexLo := OldHoverIndex;
- IndexHi := FHoverIndex;
- if FHoverIndex < OldHoverIndex then
- begin
- IndexLo := FHoverIndex;
- IndexHi := OldHoverIndex;
- end;
- for I := IndexLo to IndexHi do
- begin
- R := GetItemRect(I);
- if (R.Top >= 0) and (R.Bottom <= FHeight) and RectVisible(DC, R) then
- TTBXCustomList(Item).DrawItem(Canvas, Self, R, I, HoverIndex);
- end;
- finally
- Canvas.Handle := 0;
- Canvas.Free;
- ReleaseDC(View.Window.Handle, DC);
- end;
- TTBXCustomList(Item).HandleHover(FHoverIndex);
- end;
- end;
- procedure TTBXCustomListViewer.MouseUp(X, Y: Integer; MouseWasDownOnMenu: Boolean);
- var
- DAD: TTBDoneActionData;
- begin
- if FScrollBar <> nil then FScrollBar.StopAutoScroll;
- if MouseInScrollBar then
- begin
- inherited;
- Dec(X, FWidth - FScrollBarWidth);
- FScrollBar.MouseUp(mbLeft, X, Y);
- DAD := TTBViewAccess(TTBViewAccess(View).GetRootView).DoneActionData;
- DAD.DoneAction := tbdaNone;
- TTBViewAccess(TTBViewAccess(View).GetRootView).DoneActionData := DAD;
- MouseInScrollBar := False;
- end
- else if MouseIsDown then
- begin
- MouseIsDown := False;
- TTBXCustomList(Item).ItemIndex := FHoverIndex;
- inherited;
- DAD := TTBViewAccess(TTBViewAccess(View).GetRootView).DoneActionData;
- DAD.Sound := False;
- TTBViewAccess(TTBViewAccess(View).GetRootView).DoneActionData := DAD;
- end;
- end;
- procedure TTBXCustomListViewer.MouseWheel(WheelDelta, X, Y: Integer);
- var
- IsNegative: Boolean;
- begin
- if FScrollBar <> nil then
- begin
- Inc(FWheelAccumulator, WheelDelta);
- while Abs(FWheelAccumulator) >= WHEEL_DELTA do
- begin
- IsNegative := FWheelAccumulator < 0;
- FWheelAccumulator := Abs(FWheelAccumulator) - WHEEL_DELTA;
- if IsNegative then
- begin
- if FWheelAccumulator <> 0 then FWheelAccumulator := -FWheelAccumulator;
- FScrollBar.UpdatePosition(FScrollBar.Position + 1)
- end
- else
- FScrollBar.UpdatePosition(FScrollBar.Position - 1)
- end;
- end;
- end;
- procedure TTBXCustomListViewer.Paint(const Canvas: TCanvas;
- const ClientAreaRect: TRect; IsHoverItem, IsPushed, UseDisabledShadow: Boolean);
- begin
- { Cache some important info for later usage }
- FLastClientRect := ClientAreaRect;
- with ClientAreaRect do
- begin
- FWidth := Right - Left;
- FHeight := Bottom - Top;
- end;
- DrawItems(Canvas, ClientAreaRect);
- if FScrollBarWidth > 0 then
- begin
- if FScrollBar = nil then
- begin
- FScrollBar := TTBXScrollBar.Create;
- FScrollBar.Kind := sbVertical;
- FScrollBar.OnRedrawRequest := SBRedrawHandler;
- FScrollBar.OnChange := SBChangeHandler;
- FScrollBar.OnAutoScroll := SBAutoScrollHandler;
- end;
- FScrollBar.Bounds := Rect(ClientAreaRect.Right - FScrollBarWidth,
- ClientAreaRect.Top, ClientAreaRect.Right, ClientAreaRect.Bottom);
- FScrollBar.Range := FItemCount;
- FScrollBar.Window := FVisibleItems;
- FScrollBar.Position := FOffset;
- FScrollBar.PaintTo(Canvas);
- end;
- end;
- procedure TTBXCustomListViewer.SBAutoScrollHandler(Sender: TObject;
- var Direction, Interval: Integer);
- begin
- HandleAutoScroll(Direction, Interval);
- end;
- procedure TTBXCustomListViewer.SBChangeHandler(Sender: TObject);
- begin
- FOffset := FScrollBar.Position;
- UpdateItems;
- end;
- procedure TTBXCustomListViewer.SBRedrawHandler(Sender: TObject);
- var
- DC: HDC;
- Canvas: TCanvas;
- begin
- Canvas := TCanvas.Create;
- DC := GetDC(View.Window.Handle);
- try
- SetWindowOrgEx(DC, -BoundsRect.Left, -BoundsRect.Top, nil);
- Canvas.Handle := DC;
- FScrollBar.PaintTo(Canvas);
- finally
- Canvas.Handle := 0;
- Canvas.Free;
- ReleaseDC(View.Window.Handle, DC);
- end;
- end;
- procedure TTBXCustomListViewer.UpdateItems;
- var
- DC: HDC;
- Canvas: TCanvas;
- begin
- if Assigned(FScrollBar) then FOffset := FScrollBar.Position
- else FOffset := 0;
- Canvas := TCanvas.Create;
- DC := GetDC(View.Window.Handle);
- try
- SetWindowOrgEx(DC, -BoundsRect.Left, -BoundsRect.Top, nil);
- Canvas.Handle := DC;
- DrawItems(Canvas, FLastClientRect);
- finally
- Canvas.Handle := 0;
- Canvas.Free;
- ReleaseDC(View.Window.Handle, DC);
- end;
- end;
- //----------------------------------------------------------------------------//
- { TTBXStringList }
- constructor TTBXStringList.Create(AOwner: TComponent);
- begin
- inherited;
- FStrings := TStringList.Create;
- end;
- destructor TTBXStringList.Destroy;
- begin
- FStrings.Free;
- inherited;
- end;
- function TTBXStringList.GetCount: Integer;
- begin
- Result := FStrings.Count;
- end;
- function TTBXStringList.GetItemText(Index: Integer): string;
- begin
- Result := FStrings[Index];
- end;
- procedure TTBXStringList.SetStrings(Value: TStrings);
- begin
- FStrings.Assign(Value);
- end;
- //----------------------------------------------------------------------------//
- {$IFNDEF MPEXCLUDE}
- { TTBXUndoList }
- procedure TTBXUndoList.DrawItem(ACanvas: TCanvas; AViewer: TTBXCustomListViewer;
- const ARect: TRect; AIndex, AHoverIndex: Integer);
- const
- FillColors: array [Boolean] of TColor = (clWindow, clHighlight);
- TextColors: array [Boolean] of TColor = (clWindowText, clHighlightText);
- var
- S: string;
- R: TRect;
- begin
- ACanvas.Brush.Color := FillColors[AIndex <= AHoverIndex];
- ACanvas.FillRect(ARect);
- S := Strings[AIndex];
- if Length(S) > 0 then
- begin
- R := ARect;
- InflateRect(R, -4, 1);
- ACanvas.Font.Color := TextColors[AIndex <= AHoverIndex];
- ACanvas.Brush.Style := bsClear;
- DrawText(ACanvas.Handle, PChar(S), Length(S), R, DT_SINGLELINE or DT_VCENTER);
- ACanvas.Brush.Style := bsSolid;
- end;
- end;
- function TTBXUndoList.GetItemViewerClass(AView: TTBView): TTBItemViewerClass;
- begin
- Result := TTBXUndoListViewer;
- end;
- procedure TTBXUndoList.HandleHover(AIndex: Integer);
- begin
- ItemIndex := AIndex;
- end;
- //----------------------------------------------------------------------------//
- { TTBXUndoListViewer }
- procedure TTBXUndoListViewer.AdjustAutoScrollHover(var AIndex: Integer; Direction: Integer);
- begin
- if Direction < 0 then AIndex := FOffset
- else if Direction > 0 then AIndex := FOffset + FVisibleItems - 1;
- end;
- procedure TTBXUndoListViewer.HandleAutoScroll(var Direction, Interval: Integer);
- begin
- inherited;
- if Direction < 0 then HoverIndex := FOffset
- else if Direction > 0 then HoverIndex := FOffset + FVisibleItems - 1
- else Exit;
- TTBXCustomList(Item).HandleHover(HoverIndex);
- UpdateItems;
- end;
- {$ENDIF}
- end.
|