summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgraemeg <graemeg@ae50a9b5-8222-0410-bf8d-8a13f76226bf>2007-08-17 14:35:33 +0000
committergraemeg <graemeg@ae50a9b5-8222-0410-bf8d-8a13f76226bf>2007-08-17 14:35:33 +0000
commit003a991ccc0b05ce9a939d27313dd5ee0d9f4390 (patch)
tree551a6dfc94dfff01f77b84f19d5a255ce66f5606 /src
parent76df5b245da72230e5491c51e049c19337884ac1 (diff)
downloadfpGUI-003a991ccc0b05ce9a939d27313dd5ee0d9f4390.tar.xz
* Implemented a FileOpen and FileSave dialog. Both are the same class. It's
not 100% yet. See ToDo list in header of gui_dialogs unit. * Minor bug fix in ComboBox component and added missing (required) properties. * Fixed a bug in TfpgCustomGrid.Destroy. Creating a decendant of TfpgCustomGrid caused a crash in the destructor. * Fixed bug in ListBox where scrollbar did not move with mouse wheel input. * Added a new FileDialog example project.
Diffstat (limited to 'src')
-rw-r--r--src/gui/gui_basegrid.pas10
-rw-r--r--src/gui/gui_combobox.pas42
-rw-r--r--src/gui/gui_customgrid.pas9
-rw-r--r--src/gui/gui_dialogs.pas502
-rw-r--r--src/gui/gui_grid.pas11
-rw-r--r--src/gui/gui_listbox.pas4
6 files changed, 564 insertions, 14 deletions
diff --git a/src/gui/gui_basegrid.pas b/src/gui/gui_basegrid.pas
index 338cd1f0..6f793ff7 100644
--- a/src/gui/gui_basegrid.pas
+++ b/src/gui/gui_basegrid.pas
@@ -106,6 +106,7 @@ type
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
+ procedure Update;
end;
implementation
@@ -954,10 +955,19 @@ end;
destructor TfpgBaseGrid.Destroy;
begin
+ FOnRowChange := nil;
+ FOnFocusChange := nil;
FFont.Free;
FHeaderFont.Free;
inherited Destroy;
end;
+procedure TfpgBaseGrid.Update;
+begin
+ UpdateScrollBars;
+ FollowFocus;
+ RePaint;
+end;
+
end.
diff --git a/src/gui/gui_combobox.pas b/src/gui/gui_combobox.pas
index 75449c24..565a886c 100644
--- a/src/gui/gui_combobox.pas
+++ b/src/gui/gui_combobox.pas
@@ -27,37 +27,41 @@ type
FInternalBtn: TfpgButton;
FItems: TStringList;
FOnChange: TNotifyEvent;
+ function GetFontDesc: string;
procedure SetBackgroundColor(const AValue: TfpgColor);
procedure SetDropDownCount(const AValue: integer);
procedure DoDropDown;
procedure InternalBtnClick(Sender: TObject);
procedure InternalListBoxSelect(Sender: TObject);
procedure SetFocusItem(const AValue: integer);
+ procedure SetFontDesc(const AValue: string);
protected
FMargin: integer;
procedure SetEnabled(const AValue: boolean); override;
property DropDownCount: integer read FDropDownCount write SetDropDownCount default 8;
procedure HandleLMouseDown(x, y: integer; shiftstate: TShiftState); override;
procedure HandlePaint; override;
- property Items: TStringList read FItems;
+ property Items: TStringList read FItems; {$Note Make this read/write }
property FocusItem: integer read FFocusItem write SetFocusItem;
- property Font: TfpgFont read FFont;
property BackgroundColor: TfpgColor read FBackgroundColor write SetBackgroundColor;
- function Text: string;
+ property FontDesc: string read GetFontDesc write SetFontDesc;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
+ function Text: string;
procedure AfterConstruction; override;
+ property Font: TfpgFont read FFont;
end;
TfpgComboBox = class(TfpgCustomComboBox)
published
+ property BackgroundColor;
property DropDownCount;
- property Items;
property FocusItem;
- property BackgroundColor;
+ property FontDesc;
+ property Items;
property OnChange;
end;
@@ -187,6 +191,11 @@ begin
end;
end;
+function TfpgCustomComboBox.GetFontDesc: string;
+begin
+ Result := FFont.FontDesc;
+end;
+
procedure TfpgCustomComboBox.DoDropDown;
var
pt: TPoint;
@@ -241,11 +250,29 @@ begin
FOnChange(self);
end;
+{ Focusitem is 1 based and NOT 0 based like the Delphi ItemIndex property.
+ So at startup, FocusItem = 0 which means nothing is selected. If FocusItem = 1
+ it means the first item is selected etc. }
procedure TfpgCustomComboBox.SetFocusItem(const AValue: integer);
begin
if FFocusItem = AValue then
Exit; //==>
FFocusItem := AValue;
+
+ // do some limit check corrections
+ if FFocusItem < 0 then
+ FFocusItem := 0 // nothing is selected
+ else if FFocusItem > FItems.Count then
+ FFocusItem := FItems.Count;
+
+ RePaint;
+end;
+
+procedure TfpgCustomComboBox.SetFontDesc(const AValue: string);
+begin
+ FFont.Free;
+ FFont := fpgGetFont(AValue);
+ RePaint;
end;
procedure TfpgCustomComboBox.SetEnabled(const AValue: boolean);
@@ -302,7 +329,7 @@ begin
Canvas.FillRectangle(r);
// Draw select item's text
- if FocusItem > -1 then
+ if FocusItem > 0 then
fpgStyle.DrawString(Canvas, FMargin+1, FMargin, Text, Enabled);
Canvas.EndDraw;
@@ -323,7 +350,7 @@ begin
FDropDownCount := 8;
FWidth := 120;
FHeight := 23;
- FFocusItem := 0;
+ FFocusItem := 0; // nothing is selected
FMargin := 3;
FFont := fpgGetFont('#List');
@@ -350,6 +377,7 @@ begin
FInternalBtn.Parent := self;
FInternalBtn.ImageName := 'sys.sb.down';
FInternalBtn.ShowImage := True;
+ FInternalBtn.Anchors := [anRight, anTop];
end;
end;
diff --git a/src/gui/gui_customgrid.pas b/src/gui/gui_customgrid.pas
index 58c21f3d..1cda07ef 100644
--- a/src/gui/gui_customgrid.pas
+++ b/src/gui/gui_customgrid.pas
@@ -110,8 +110,8 @@ begin
while n > AValue do
begin
TGridColumn(FColumns.Items[n-1]).Free;
+ FColumns.Delete(n-1);
dec(n);
- FColumns.Count := n;
end;
end;
UpdateScrollBars;
@@ -170,7 +170,12 @@ end;
destructor TfpgCustomGrid.Destroy;
begin
- SetColumnCount(0);
+ while FColumns.Count > 0 do
+ begin
+ TGridColumn(FColumns.Items[0]).Free;
+ FColumns.Delete(0);
+ end;
+
FColumns.Free;
inherited Destroy;
end;
diff --git a/src/gui/gui_dialogs.pas b/src/gui/gui_dialogs.pas
index 76648a68..a99a40a0 100644
--- a/src/gui/gui_dialogs.pas
+++ b/src/gui/gui_dialogs.pas
@@ -6,6 +6,14 @@ unit gui_dialogs;
{$mode objfpc}{$H+}
+{
+ TODO:
+ * Try and abstract the code to remove all IFDEF's
+ * Combobox dropdown in FileDialog doesn't function to do ModolForm being used.
+ * File Selection not working 100% in FileDialog
+ * Moving through directories not working 100% yet in FileDialog.
+}
+
{.$Define DEBUG}
interface
@@ -19,7 +27,10 @@ uses
gui_label,
gui_listbox,
gui_checkbox,
- gui_edit;
+ gui_edit,
+ gui_grid,
+ gui_combobox,
+ gui_bevel;
type
@@ -92,6 +103,50 @@ type
{ This well set the sample text or font preview text to AText.}
procedure SetSampleText(AText: string);
end;
+
+
+ TfpgFileDialog = class(TfpgBaseDialog)
+ private
+ FOpenMode: boolean;
+ FFilterList: TStringList;
+ FFilter: string;
+ procedure SetFilter(const Value: string);
+ function GetShowHidden: boolean;
+ procedure SetShowHidden(const Value: boolean);
+ procedure ListChanged(Sender: TObject; ARow: integer);
+ procedure InitializeComponents;
+ protected
+ procedure HandleKeyPress(var keycode: word; var shiftstate: TShiftState; var consumed: boolean); override;
+ procedure btnOKClick(Sender: TObject); override;
+ procedure SetCurrentDirectory(const ADir: string);
+ public
+ chlDir: TfpgComboBox;
+ grid: TfpgFileGrid;
+ btnUpDir: TfpgButton;
+ btnDirNew: TfpgButton;
+ btnShowHidden: TfpgButton;
+ panel1: TfpgBevel;
+ lbFileInfo: TfpgLabel;
+ edFilename: TfpgEdit;
+ chlFilter: TfpgComboBox;
+ lb1: TfpgLabel;
+ lb2: TfpgLabel;
+ FileName: string;
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ procedure DirChange(Sender: TObject);
+ procedure FilterChange(Sender: TObject);
+ procedure GridDblClick(Sender: TObject; x, y: integer; var btnstate, shiftstate: word);
+ procedure UpDirClick(Sender: TObject);
+ function SelectFile(const AFilename: string): boolean;
+ procedure ProcessFilterString;
+ function GetFileFilter: string;
+ property Filter: string read FFilter write SetFilter;
+ function RunOpenFile: boolean;
+ function RunSaveFile: boolean;
+ property ShowHidden: boolean read GetShowHidden write SetShowHidden;
+ end;
+
{ A convenience function to show a message using the TfpgMessageBox class.}
procedure ShowMessage(AMessage, ATitle: string); overload;
@@ -106,9 +161,10 @@ implementation
uses
gfxbase,
+ gfx_widget,
gfx_utf8utils;
-
-
+
+
procedure ShowMessage(AMessage, ATitle: string);
var
frm: TfpgMessageBox;
@@ -631,5 +687,445 @@ begin
edSample.Text := FSampleText;
end;
+{ TfpgFileDialog }
+
+procedure TfpgFileDialog.ListChanged(Sender: TObject; ARow: integer);
+var
+ s : string;
+begin
+ if grid.CurrentEntry = nil then
+ Exit; //==>
+ s := grid.CurrentEntry.Name;
+
+ if grid.CurrentEntry.IsLink then
+ s := s + ' -> ' + grid.CurrentEntry.LinkTarget;
+
+ if grid.CurrentEntry.EntryType <> etDir then
+ edFileName.Text := grid.CurrentEntry.Name;
+
+ btnOK.Enabled := grid.CurrentEntry.EntryType = etFile;
+
+ lbFileInfo.Text := s;
+end;
+
+procedure TfpgFileDialog.SetFilter(const Value: string);
+begin
+ FFilter := Value;
+ ProcessFilterString;
+end;
+
+function TfpgFileDialog.GetShowHidden: boolean;
+begin
+ Result := btnShowHidden.Down;
+end;
+
+procedure TfpgFileDialog.SetShowHidden(const Value: boolean);
+begin
+ btnShowHidden.Down := Value;
+end;
+
+procedure TfpgFileDialog.InitializeComponents;
+begin
+ chlDir := TfpgComboBox.Create(self);
+ with chlDir do
+ begin
+ SetPosition(8, 12, 526, 22);
+ Anchors := [anLeft, anRight, anTop];
+ FontDesc := '#List';
+ OnChange := @DirChange;
+ end;
+
+ grid := TfpgFileGrid.Create(self);
+ with grid do
+ begin
+ SetPosition(8, 44, 622, 200);
+ Anchors := [anLeft, anRight, anTop, anBottom];
+ OnRowChange := @ListChanged;
+// OnDoubleClick := @GridDblClick;
+ end;
+
+ btnUpDir := TfpgButton.Create(self);
+ with btnUpDir do
+ begin
+ SetPosition(540, 11, 26, 24);
+ Anchors := [anRight, anTop];
+ Text := '';
+ FontDesc := '#Label1';
+ ImageName := 'stdimg.folderup';
+ ModalResult := 0;
+ Focusable := False;
+ OnClick := @UpDirClick;
+ end;
+
+ btnDirNew := TfpgButton.Create(self);
+ with btnDirNew do
+ begin
+ SetPosition(572, 11, 26, 24);
+ Anchors := [anRight, anTop];
+ Text := '';
+ FontDesc := '#Label1';
+ ImageName := 'stdimg.foldernew';
+ ModalResult := 0;
+ Focusable := False;
+ end;
+
+ btnShowHidden := TfpgButton.Create(self);
+ with btnShowHidden do
+ begin
+ SetPosition(604, 11, 26, 24);
+ Anchors := [anRight, anTop];
+ Text := '';
+ FontDesc := '#Label1';
+ ImageName := 'stdimg.hidden';
+ ModalResult := 0;
+ Focusable := False;
+ GroupIndex := 1;
+ AllowAllUp := True;
+ OnClick := @DirChange;
+ end;
+
+ { Create lower Panel details }
+
+ panel1 := TfpgBevel.Create(self);
+ with panel1 do
+ begin
+ SetPosition(8, 253, 622, 25);
+ Anchors := [anLeft, anRight, anBottom];
+ Shape := bsBox;
+ Style := bsLowered;
+ end;
+
+ lbFileInfo := TfpgLabel.Create(panel1);
+ with lbFileInfo do
+ begin
+ SetPosition(5, 4, 609, 16);
+ Anchors := [anLeft, anRight, anTop];
+ Text := ' ';
+ FontDesc := '#Label1';
+ end;
+
+ edFilename := TfpgEdit.Create(self);
+ with edFilename do
+ begin
+ SetPosition(8, 301, 622, 22);
+ Anchors := [anLeft, anRight, anBottom];
+ Text := '';
+ FontDesc := '#Edit1';
+ end;
+
+ { Filter section }
+
+ chlFilter := TfpgComboBox.Create(self);
+ with chlFilter do
+ begin
+ SetPosition(8, 345, 622, 22);
+ Anchors := [anLeft, anRight, anBottom];
+ FontDesc := '#List';
+ OnChange := @FilterChange;
+ end;
+
+ lb1 := TfpgLabel.Create(self);
+ with lb1 do
+ begin
+ SetPosition(8, 283, 80, 16);
+ Anchors := [anLeft, anBottom];
+ Text := 'Filename:';
+ FontDesc := '#Label1';
+ end;
+
+ lb2 := TfpgLabel.Create(self);
+ with lb2 do
+ begin
+ SetPosition(8, 327, 64, 16);
+ Anchors := [anLeft, anBottom];
+ Text := 'File type:';
+ FontDesc := '#Label1';
+ end;
+
+ ActiveWidget := grid;
+ FileName := '';
+ Filter := 'All Files (*)|*';
+end;
+
+procedure TfpgFileDialog.HandleKeyPress(var keycode: word; var shiftstate: TShiftState; var consumed: boolean);
+var
+ e: TFileEntry;
+begin
+ if not consumed then
+ begin
+ if (keycode = keyReturn) and (ActiveWidget = grid) then
+ begin
+ e := grid.CurrentEntry;
+ if (e <> nil) and (e.EntryType = etDir) then
+ begin
+ SetCurrentDirectory(e.Name);
+ consumed := True;
+ end;
+ end;
+ end;
+ if not consumed then
+ inherited HandleKeyPress(keycode, shiftstate, consumed);
+end;
+
+procedure TfpgFileDialog.btnOKClick(Sender: TObject);
+begin
+ if not FOpenMode or SysUtils.FileExists(edFileName.Text) then
+ begin
+ ModalResult := 1;
+ end;
+
+ if ModalResult > 0 then
+ FileName := ExpandFileName(edFileName.Text);
+end;
+
+constructor TfpgFileDialog.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ WindowTitle := 'File Selection';
+ Width := 640;
+ Height := 410; // 460;
+ WindowPosition := wpScreenCenter;
+ FSpacing := 10;
+
+ FFilterList := TStringList.Create;
+
+ InitializeComponents;
+
+ // position standard dialog buttons
+ btnCancel.Left := Width - FDefaultButtonWidth - FSpacing;
+ btnCancel.Top := Height - btnCancel.Height - FSpacing;
+ btnOK.Left := btnCancel.Left - FDefaultButtonWidth - 6;
+ btnOK.Top := btnCancel.Top;
+end;
+
+destructor TfpgFileDialog.Destroy;
+begin
+ FFilterList.Free;
+ inherited Destroy;
+end;
+
+procedure TfpgFileDialog.DirChange(Sender: TObject);
+begin
+ SetCurrentDirectory(chlDir.Text);
+end;
+
+procedure TfpgFileDialog.FilterChange(Sender: TObject);
+begin
+ SetCurrentDirectory('.');
+end;
+
+procedure TfpgFileDialog.GridDblClick(Sender: TObject; x, y: integer;
+ var btnstate, shiftstate: word);
+begin
+
+end;
+
+procedure TfpgFileDialog.UpDirClick(Sender: TObject);
+begin
+ SetCurrentDirectory('..');
+end;
+
+procedure TfpgFileDialog.SetCurrentDirectory(const ADir: string);
+var
+ ds: string;
+ n: integer;
+ rootadd: integer;
+ fsel: string;
+{$ifdef Win32}
+ drvind: integer;
+ drvs: string;
+{$endif}
+begin
+ GetDir(0, ds);
+ fsel := ExtractFileName(ds);
+
+ if not SetCurrentDir(ADir) then
+ begin
+ ShowMessage('Could not open the directory ' + ADir, 'Error');
+ Exit; //==>
+ end;
+
+ chlDir.Items.Clear;
+ if ADir <> '..' then
+ fsel := '';
+
+ rootadd := 1;
+
+ {$IFDEF MSWINDOWS}
+ // making drive list 1
+ drvind := -1;
+ if Copy(ds, 2, 1) = ':' then
+ drvind := ord(UpCase(ds[1]))-ord('A');
+ n := 0;
+ while n < drvind do
+ begin
+ drvs := chr(n+ord('A'))+':\';
+ if Windows.GetDriveType(PChar(drvs)) <> 1 then
+ begin
+ chlDir.Items.Add(u8(drvs));
+ end;
+ inc(n);
+ end;
+ {$ENDIF}
+
+ {$IFDEF UNIX}
+ if Copy(ds, 1, 1) <> DirectorySeparator then
+ ds := DirectorySeparator + ds;
+ {$ENDIF}
+
+ n := 1;
+ while n < Length(ds) do
+ begin
+ if ds[n] = DirectorySeparator then
+ begin
+ chlDir.Items.Add(Copy(ds, 1, n-1+rootadd));
+ rootadd := 0;
+ end;
+ inc(n);
+ end;
+
+ chlDir.Items.Add(ds);
+ chlDir.FocusItem := chlDir.Items.Count;
+
+ {$IFDEF MSWINDOWS}
+ // making drive list 2
+ n := drvind+1;
+ if n < 0 then n := 0;
+ while n <= 25 do
+ begin
+ drvs := chr(n+ord('A'))+':\';
+ if Windows.GetDriveType(PChar(drvs)) <> 1 then
+ begin
+ chlDir.Items.Add(u8(drvs));
+ end;
+ inc(n);
+ end;
+ {$ENDIF}
+
+ grid.FileList.ReadDirectory(GetFileFilter, ShowHidden);
+ grid.FileList.Sort(soFileName);
+ grid.Update;
+
+ if fsel <> '' then
+ SelectFile(fsel)
+ else
+ grid.FocusRow := 1;
+end;
+
+function TfpgFileDialog.SelectFile(const AFilename: string): boolean;
+var
+ n : integer;
+begin
+ for n:=1 to grid.FileList.Count do
+ begin
+ if grid.FileList.Entry[n].Name = AFilename then
+ begin
+ grid.FocusRow := n;
+ Result := True;
+ Exit; //==>
+ end;
+ end;
+ Result := False;
+end;
+
+procedure TfpgFileDialog.ProcessFilterString;
+var
+ p: integer;
+ s: string;
+ fs: string;
+ fm: string;
+begin
+ s := FFilter;
+ FFilterList.Clear;
+ chlFilter.Items.Clear;
+
+ repeat
+ fs := '';
+ fm := '';
+ p := pos('|', s);
+ if p > 0 then
+ begin
+ fs := Copy(s, 1, p-1);
+ Delete(s, 1, p);
+ p := pos('|', s);
+ if p > 0 then
+ begin
+ fm := Copy(s, 1, p-1);
+ Delete(s, 1, p);
+ end
+ else
+ begin
+ fm := s;
+ s := '';
+ end;
+ end;
+
+ if (fs <> '') and (fm <> '') then
+ begin
+ chlFilter.Items.Add(fs);
+ FFilterList.Add(fm);
+ end;
+ until (fs = '') or (fm = ''); { repeat/until }
+end;
+
+function TfpgFileDialog.GetFileFilter: string;
+var
+ i: integer;
+begin
+ i := chlFilter.FocusItem;
+ if (i > 0) and (i <= FFilterList.Count) then
+ Result := FFilterList[i-1]
+ else
+ Result := '*';
+end;
+
+function TfpgFileDialog.RunOpenFile: boolean;
+var
+ sdir: string;
+ fname: string;
+begin
+ FOpenMode := True;
+ sdir := ExtractFileDir(FileName);
+ if sdir = '' then
+ sdir := '.';
+ SetCurrentDirectory(sdir);
+ fname := ExtractFileName(FileName);
+ if not SelectFile(fname) then
+ edFilename.Text := fname;
+
+ WindowTitle := 'Open File...';
+ btnOK.ImageName := 'stdimg.open';
+ btnOK.Text := 'Open';
+
+ if ShowModal > 0 then
+ Result := True
+ else
+ Result := False;
+end;
+
+function TfpgFileDialog.RunSaveFile: boolean;
+var
+ sdir: string;
+ fname: string;
+begin
+ FOpenMode := False;
+ sdir := ExtractFileDir(FileName);
+ if sdir = '' then
+ sdir := '.';
+ SetCurrentDirectory(sdir);
+ fname := ExtractFileName(FileName);
+ if not SelectFile(fname) then
+ edFilename.Text := fname;
+
+ WindowTitle := 'Save File...';
+ btnOK.ImageName := 'stdimg.save';
+ btnOK.Text := 'Save';
+
+ if ShowModal > 0 then
+ Result := True
+ else
+ Result := False;
+end;
+
end.
diff --git a/src/gui/gui_grid.pas b/src/gui/gui_grid.pas
index f69bd964..fb203677 100644
--- a/src/gui/gui_grid.pas
+++ b/src/gui/gui_grid.pas
@@ -100,6 +100,12 @@ type
property FixedFont: TfpgFont read FFixedFont;
property FileList: TFileList read FFileList;
property DefaultRowHeight;
+ published
+ property RowCount;
+ property ColumnCount;
+ property Columns;
+ property FocusRow;
+ property OnRowChange;
end;
@@ -343,7 +349,8 @@ end;
procedure TFileList.Sort(AOrder: TFileListSortOrder);
var
newl: TList;
- n, i: integer;
+ n: integer;
+ i: integer;
e: TFileEntry;
function IsBefore(newitem, item: TFileEntry): boolean;
@@ -505,6 +512,7 @@ begin
FFileList := TFileList.Create;
inherited Create(AOwner);
ColumnCount := 0;
+ RowCount := 0;
FFixedFont := fpgGetFont('Courier New-9');
{$Note Abstract this! No IFDEF's allowed!!! }
@@ -530,6 +538,7 @@ end;
destructor TfpgFileGrid.Destroy;
begin
+ OnRowChange := nil;
FFixedFont.Free;
FFileList.Free;
inherited Destroy;
diff --git a/src/gui/gui_listbox.pas b/src/gui/gui_listbox.pas
index 825c36de..0933c211 100644
--- a/src/gui/gui_listbox.pas
+++ b/src/gui/gui_listbox.pas
@@ -184,7 +184,8 @@ begin
VHeight := Height - 4;
HWidth := Width - 4;
- if FScrollBar.Visible then Dec(HWidth, FScrollBar.Width);
+ if FScrollBar.Visible then
+ Dec(HWidth, FScrollBar.Width);
FScrollBar.Top := 2;
FScrollBar.Left := Width - FScrollBar.Width - 2;
@@ -214,6 +215,7 @@ begin
FScrollBar.SliderSize := 1;
FScrollBar.Max := ItemCount-pn+1;
FScrollBar.Position := FFirstItem;
+ FScrollBar.RepaintSlider;
end;
end;