mirror of
				https://gitlab.com/freepascal.org/lazarus/lazarus.git
				synced 2025-11-04 13:29:26 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			216 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			216 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
{
 | 
						|
 *****************************************************************************
 | 
						|
  This file is part of LazUtils.
 | 
						|
 | 
						|
  See the file COPYING.modifiedLGPL.txt, included in this distribution,
 | 
						|
  for details about the license.
 | 
						|
 *****************************************************************************
 | 
						|
 | 
						|
  Author: Jesus Reyes
 | 
						|
 | 
						|
  Abstract:
 | 
						|
    A dynamic 2-dimensional array of Pointers.
 | 
						|
    Used for TCustomGrid, TDrawGrid and TStringGrid.
 | 
						|
}
 | 
						|
 | 
						|
unit DynamicArray;
 | 
						|
 | 
						|
{$mode objfpc}{$H+}
 | 
						|
 | 
						|
interface
 | 
						|
 | 
						|
uses
 | 
						|
  Classes, SysUtils; 
 | 
						|
 | 
						|
type
 | 
						|
  EArray=Class(Exception);
 | 
						|
  
 | 
						|
  TOnNotifyItem = Procedure(Sender: TObject; Col,Row: integer; Var Item: Pointer) of Object;
 | 
						|
  TOnExchangeItem = procedure (Sender: TObject; Index, WithIndex: Integer) of Object;
 | 
						|
 | 
						|
  TPointerPointerArray=Class
 | 
						|
  private
 | 
						|
    FCols: TFpList;
 | 
						|
    FOnDestroyItem: TOnNotifyItem;
 | 
						|
    FOnNewItem: TonNotifyItem;
 | 
						|
    function Getarr(Col, Row: Integer): Pointer;
 | 
						|
    procedure Setarr(Col, Row: Integer; const AValue: Pointer);
 | 
						|
    procedure ClearCol(L: TFpList; Col: Integer);
 | 
						|
    procedure Aumentar_Rows(col,Rows: Integer; L: TFpList);
 | 
						|
    procedure DestroyItem(Col,Row: Integer; P: Pointer);
 | 
						|
  public
 | 
						|
    constructor Create;
 | 
						|
    destructor Destroy; override;
 | 
						|
    procedure SetLength(Cols,Rows: Integer);
 | 
						|
 | 
						|
    procedure DeleteColRow(IsColumn: Boolean; Index: Integer);
 | 
						|
    procedure MoveColRow(IsColumn:Boolean; FromIndex, ToIndex: Integer);
 | 
						|
    procedure ExchangeColRow(IsColumn:Boolean; Index, WithIndex: Integer);
 | 
						|
    procedure Clear;
 | 
						|
    
 | 
						|
    Property Arr[Col,Row: Integer]: Pointer read GetArr write SetArr; default;
 | 
						|
    Property OnDestroyItem: TOnNotifyItem read FOnDestroyItem write FOnDestroyItem;
 | 
						|
    Property OnNewItem: TOnNotifyItem read FOnNewItem write FOnNewItem;
 | 
						|
  end;
 | 
						|
 | 
						|
implementation
 | 
						|
 | 
						|
{ TPointerPointerArray }
 | 
						|
 | 
						|
function TPointerPointerArray.Getarr(Col, Row: Integer): Pointer;
 | 
						|
begin
 | 
						|
  // Checar dimensiones
 | 
						|
  Result := TFpList(FCols[Col])[Row];
 | 
						|
end;
 | 
						|
 | 
						|
procedure TPointerPointerArray.Setarr(Col, Row: Integer; const AValue: Pointer);
 | 
						|
begin
 | 
						|
  // Checar dimensiones
 | 
						|
  TFpList(FCols[Col])[Row] := AValue;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TPointerPointerArray.ClearCol(L: TFpList; Col: Integer);
 | 
						|
var
 | 
						|
   j: Integer;
 | 
						|
begin
 | 
						|
  if L<>nil then begin
 | 
						|
    for j:=0 to L.Count-1 do DestroyItem(Col,J, L[J]);
 | 
						|
    L.Clear;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TPointerPointerArray.Clear;
 | 
						|
var
 | 
						|
   i: Integer;
 | 
						|
begin
 | 
						|
  {$Ifdef dbgMem}DebugLn('TArray.Clear');{$endif}
 | 
						|
  for i:=0 to FCols.Count-1 do begin
 | 
						|
    ClearCol(TFpList(FCols[i]), i);
 | 
						|
    TFpList(FCols[i]).Free;
 | 
						|
  end;
 | 
						|
  FCols.Clear;
 | 
						|
end;
 | 
						|
 | 
						|
constructor TPointerPointerArray.Create;
 | 
						|
begin
 | 
						|
  inherited Create;
 | 
						|
  FCols := TFpList.Create;
 | 
						|
end;
 | 
						|
 | 
						|
destructor TPointerPointerArray.Destroy;
 | 
						|
begin
 | 
						|
  {$Ifdef dbgMem}DebugLn('TArray.Destroy FCols.Count=',dbgs(FCols.Count));{$endif}
 | 
						|
  Clear;
 | 
						|
  FCols.free;
 | 
						|
  inherited Destroy;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TPointerPointerArray.Aumentar_Rows(col,rows: Integer; L: TFpList);
 | 
						|
var
 | 
						|
   i,j: Integer;
 | 
						|
   P: Pointer;
 | 
						|
begin
 | 
						|
  //DebugLn('TArray.Aumentar_Rows: Col=',Col,' Rows=',Rows);
 | 
						|
  i:=L.Count;
 | 
						|
  j:=Rows-L.Count;
 | 
						|
  while j>0 do begin
 | 
						|
    P:=nil;
 | 
						|
    if Assigned(OnNewItem) Then OnNewItem(Self, col, i, P);
 | 
						|
    L.Add(P);
 | 
						|
    dec(j);
 | 
						|
    inc(i);
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TPointerPointerArray.DestroyItem(Col, Row: Integer; P: Pointer);
 | 
						|
begin
 | 
						|
  if (P<>nil)And Assigned(OnDestroyItem) then OnDestroyItem(Self, Col, Row, P);
 | 
						|
end;
 | 
						|
 | 
						|
procedure TPointerPointerArray.SetLength(Cols, Rows: Integer);
 | 
						|
var
 | 
						|
   i,j: integer;
 | 
						|
   L: TFpList;
 | 
						|
   //P: Pointer;
 | 
						|
Begin
 | 
						|
  {$IfDef DbgMem}DebugLn('TArray.SetLength: Cols=',dbgs(Cols),' Rows=',dbgs(Rows));{$Endif}
 | 
						|
  //
 | 
						|
  // Ajustar columnas
 | 
						|
  //
 | 
						|
  if FCols.Count>Cols then begin
 | 
						|
    // Hay mas columnas de las que debe.
 | 
						|
    // Destruir las columnas innecesarias
 | 
						|
    for i:=Cols to fCols.Count-1 do begin
 | 
						|
      L:=TFpList(FCols[i]);
 | 
						|
      ClearCol(L, i);
 | 
						|
      FreeAndNil(L);
 | 
						|
    end;
 | 
						|
  end;
 | 
						|
  FCols.Count:=Cols;
 | 
						|
     
 | 
						|
  //
 | 
						|
  // Ajustar Renglones
 | 
						|
  //
 | 
						|
  for i:=0 to fCols.Count-1 do begin
 | 
						|
    L:=TFpList(FCols[i]);
 | 
						|
    if L=nil then L:=TFpList.Create;
 | 
						|
    if L.Count>Rows then begin
 | 
						|
      for j:=Rows to L.Count-1 do DestroyItem(i,j,L[j]);
 | 
						|
      L.Count:=Rows;
 | 
						|
    end;
 | 
						|
    Aumentar_Rows(i, Rows, L);
 | 
						|
    FCols[i]:=L;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TPointerPointerArray.DeleteColRow(IsColumn: Boolean; Index: Integer);
 | 
						|
var
 | 
						|
  i: Integer;
 | 
						|
  L: TFpList;
 | 
						|
begin
 | 
						|
  if IsColumn then begin
 | 
						|
    {$Ifdef dbgMem}DebugLn('TArray.DeleteColRow Col=',dbgs(Index));{$endif}
 | 
						|
    L:=TFpList(FCols[Index]);
 | 
						|
    If L<>nil then begin
 | 
						|
      ClearCol(L, Index);
 | 
						|
      FCols.Delete(Index);
 | 
						|
      L.Free;
 | 
						|
    end;
 | 
						|
  end else begin
 | 
						|
    {$Ifdef dbgMem}DebugLn('TArray.DeleteColRow Row=',dbgs(Index));{$endif}
 | 
						|
    for i:=0 to fCols.Count - 1 do begin
 | 
						|
      L:=TFpList(fcols[i]);
 | 
						|
      if L<>nil then begin
 | 
						|
        DestroyItem(i, Index, L[Index]);
 | 
						|
        L.Delete(Index);
 | 
						|
      end;
 | 
						|
    end;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TPointerPointerArray.MoveColRow(IsColumn: Boolean; FromIndex, ToIndex: Integer);
 | 
						|
var
 | 
						|
  i: Integer;
 | 
						|
begin
 | 
						|
  If IsColumn then begin
 | 
						|
    FCols.Move(FromIndex, ToIndex);
 | 
						|
  end else begin
 | 
						|
    for i:=0 to FCols.Count-1 do
 | 
						|
      TFpList(Fcols[i]).Move(FromIndex,ToIndex);
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
procedure TPointerPointerArray.ExchangeColRow(IsColumn: Boolean; Index, WithIndex: Integer);
 | 
						|
var
 | 
						|
  i: Integer;
 | 
						|
begin
 | 
						|
  if IsColumn then begin
 | 
						|
    FCols.Exchange(Index, WithIndex);
 | 
						|
  end else begin
 | 
						|
    for i:=0 to FCols.Count-1 do
 | 
						|
      TFpList(FCols[i]).Exchange(Index, WithIndex);
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
end.
 |