unit Unit3; interface uses WebCore, WebUI, WebForms, WebCtrls, WebCtnrs, WebLabels, AlbumItem, WebBtns, WebData, WebGrids, WebEdits; type TForm3 = class(TForm) ScrollBox: TScrollPanel; Label1: TLabel; lbScrollTop: TLabel; Label2: TLabel; lbUpperRow: TLabel; PanelDummy: TBasicPanel; Label3: TLabel; lbLowerRow: TLabel; Albums: TDataSet; procedure Form3Create(Sender: TObject); procedure ScrollBoxScroll(Sender: TObject); procedure AlbumsAfterLoad(Sender: TObject); function GetItemWidth(AColumns: integer): integer; private { Private declarations } RowsDone: Array of integer; RowsTotal: integer; procedure CreateAlbumItems(AFirstRow, ALastRow: integer); function RowExists(ARow: integer): Boolean; public { Public declarations } end; var Form3: TForm3; const ROW_HEIGHT = 150; VISIBLE_ROWS = 4; VISIBLE_SCOPE = 5; COLUMNS = 2; implementation procedure TForm3.Form3Create(Sender: TObject); begin PanelDummy.Left := ScrollBox.Width; SetLength(RowsDone,0); Database.DatabaseName := 'MySpotify'; Database.BaseURL := 'databases'; Database.LoadRows(Albums); end; function TForm3.GetItemWidth(AColumns: integer): integer; begin Result := (Scrollbox.Width - Scrollbox.VertScrollbar.Width - Scrollbox.VertScrollbar.Margins.Right - Scrollbox.VertScrollbar.Margins.Left) div AColumns; end; procedure TForm3.ScrollBoxScroll(Sender: TObject); var TempScrollTop: Integer; TempUpperRow, TempLowerRow: integer; begin TempScrollTop := ScrollBox.ScrollTop; lbScrollTop.Caption := IntToStr(TempScrollTop); TempUpperRow := Floor(TempScrollTop / ROW_HEIGHT); TempLowerRow := TempUpperRow + VISIBLE_SCOPE; lbUpperRow.Caption := IntToStr(TempUpperRow); lbLowerRow.Caption := IntToStr(TempLowerRow); if TempLowerRow > RowsTotal -1 then TempLowerRow := RowsTotal -1; CreateAlbumItems(TempUpperRow, TempLowerRow); end; procedure TForm3.CreateAlbumItems(AFirstRow, ALastRow: integer); var i, z, Temp, TempItemWidth: integer; TempItem: TAlbumItem; begin TempItemWidth := GetItemWidth(COLUMNS); ScrollBox.BeginUpdate; try for i := AFirstRow to ALastRow do begin if i = 0 then Albums.MoveTo(1) else Albums.MoveTo((i * 2) + 1); if not RowExists(i) then begin for z := 0 to 1 do begin if not Albums.EOF then begin TempItem := TAlbumItem.Create(ScrollBox); with TempItem do begin Width := TempItemWidth; Height := ROW_HEIGHT; Top := i * ROW_HEIGHT; if z = 0 then Left := 0 else Left := TempItemWidth; AlbumName := Albums.Columns['Name'].asString; AlbumArtists := Albums.Columns['Artists'].asString; AlbumURL := Albums.Columns['ImageURL_Medium'].asString; Animations.Visible.Duration := 200; Animations.Visible.Style := asLinear; end; Albums.Next; end; end; Temp := Length(RowsDone); Inc(Temp); SetLength(RowsDone,Temp); RowsDone[Temp] := i; end; end; finally ScrollBox.EndUpdate; end; end; function TForm3.RowExists(ARow: integer): Boolean; var i: integer; begin Result := false; for i := 0 to Length(RowsDone) -1 do begin if RowsDone[i] = ARow then begin Result := true; Break; end; end; end; procedure TForm3.AlbumsAfterLoad(Sender: TObject); begin RowsTotal := Ceil(Albums.RowCount / 2); PanelDummy.Height := RowsTotal * ROW_HEIGHT; CreateAlbumItems(0,VISIBLE_ROWS); end; end.