| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- unit BCListBoxEx;
- {$mode delphi}
- interface
- uses
- Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
- LCLType;
- type
- TBCListBoxEx = class(TCustomControl)
- private
- mousepos: TPoint;
- scrolly: integer;
- fitems: TStringList;
- itemselected: integer;
- itemheight: integer;
- lastitem: integer;
- invalidatecount: integer;
- scrollwidth: integer;
- function GetItemRect(index: integer): TRect;
- function GetItemVertically(y: integer): integer;
- procedure ScrollToItemTop();
- procedure ScrollToItemBottom();
- procedure ScrollToItem(index: integer);
- function ItemIsVisible(index: integer): boolean;
- protected
- procedure Click; override;
- procedure KeyDown(var Key: word; Shift: TShiftState); override;
- procedure MouseMove(Shift: TShiftState; X, Y: integer); override;
- function DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): boolean; override;
- function DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): boolean; override;
- procedure Paint; override;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- published
- property Align;
- property Items: TStringList read Fitems;
- end;
- procedure Register;
- implementation
- procedure Register;
- begin
- RegisterComponents('BGRA Controls', [TBCListBoxEx]);
- end;
- procedure TBCListBoxEx.Click;
- var
- tempitem: integer;
- begin
- tempitem := GetItemVertically(mousepos.Y);
- if tempitem <> itemselected then
- begin
- itemselected := tempitem;
- Invalidate;
- end;
- end;
- constructor TBCListBoxEx.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- scrolly := 0;
- itemheight := 150;
- scrollwidth := 20;
- lastitem := -1;
- invalidatecount := 0;
- itemselected := -1;
- fitems := TStringList.Create;
- end;
- destructor TBCListBoxEx.Destroy;
- begin
- items.Free;
- end;
- procedure TBCListBoxEx.KeyDown(var Key: word; Shift: TShiftState);
- var
- tempitem: integer;
- begin
- case key of
- vk_down:
- begin
- tempitem := itemselected + 1;
- if (tempitem < items.Count) then
- begin
- itemselected := tempitem;
- if not ItemIsVisible(itemselected) then
- ScrollToItemBottom();
- if not ItemIsVisible(itemselected) then
- ScrollToItem(itemselected);
- Invalidate;
- end;
- end;
- vk_up:
- begin
- tempitem := itemselected - 1;
- if (tempitem >= 0) then
- begin
- itemselected := tempitem;
- if not ItemIsVisible(itemselected) then
- ScrollToItemTop();
- if not ItemIsVisible(itemselected) then
- ScrollToItem(itemselected);
- Invalidate;
- end;
- end;
- end;
- end;
- procedure TBCListBoxEx.MouseMove(Shift: TShiftState; X, Y: integer);
- var
- tempitem: integer;
- begin
- mousepos := Point(x, y);
- tempitem := GetItemVertically(mousepos.Y);
- if tempitem <> lastitem then
- begin
- lastitem := tempitem;
- Invalidate;
- end;
- end;
- function TBCListBoxEx.DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): boolean;
- var
- r: TRect;
- begin
- result := False;
- r := GetItemRect(items.Count - 1);
- if (r.Bottom >= Height) then
- begin
- result := True;
- scrolly := scrolly - itemheight;
- Invalidate;
- end;
- end;
- function TBCListBoxEx.DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): boolean;
- var
- lastscroll: integer;
- begin
- result := False;
- lastscroll := scrolly;
- scrolly := scrolly + itemheight;
- if (scrolly > 0) then
- scrolly := 0;
- if scrolly <> lastscroll then
- begin
- result := True;
- Invalidate;
- end;
- end;
- procedure TBCListBoxEx.Paint;
- var
- i: integer;
- r: TRect;
- style: TTextStyle;
- start: integer;
- begin
- style.Alignment := taCenter;
- style.Layout := tlCenter;
- start := -1;
- for i := trunc(abs(scrolly) / itemheight) to items.Count - 1 do
- begin
- r := GetItemRect(i);
- if (r.Top < Height) then
- begin
- if start = -1 then
- start := i;
- Canvas.Brush.Color := clGreen;
- if (GetItemVertically(mousepos.Y) = i) then
- canvas.Brush.Color := clMoneyGreen;
- if (itemselected = i) then
- canvas.Brush.Color := clBlue;
- Canvas.Rectangle(r);
- Canvas.Font.Color := clWhite;
- Canvas.TextRect(r, 0, 0, items[i], style);
- Caption := IntToStr(start) + '..' + IntToStr(i);
- end
- else
- break;
- end;
- Canvas.Brush.Color := clGray;
- Canvas.Rectangle(Width - scrollwidth, 0, Width, Height);
- Canvas.Font.Color := clRed;
- Canvas.TextOut(10, 10, IntToStr(invalidatecount));
- Inc(invalidatecount);
- end;
- function TBCListBoxEx.GetItemRect(index: integer): TRect;
- begin
- Result := Rect(0, (index * itemheight) + scrolly, Width - scrollwidth,
- (index * itemheight) + scrolly + itemheight);
- end;
- function TBCListBoxEx.GetItemVertically(y: integer): integer;
- var
- i: integer;
- begin
- i := trunc(abs(scrolly) / itemheight);
- Result := i + trunc(y / itemheight);
- if (Result > items.Count) or (Result < 0) then
- Result := -1;
- end;
- procedure TBCListBoxEx.ScrollToItemTop();
- begin
- scrolly := scrolly + itemheight;
- end;
- procedure TBCListBoxEx.ScrollToItemBottom();
- begin
- scrolly := scrolly - itemheight;
- end;
- procedure TBCListBoxEx.ScrollToItem(index: integer);
- begin
- scrolly := -itemheight * index;
- end;
- function TBCListBoxEx.ItemIsVisible(index: integer): boolean;
- var
- r: TRect;
- begin
- r := GetItemRect(index);
- Result := Rect(0, 0, Width, Height).Contains(r);
- end;
- end.
|