2012-01-15 6 views
6

私と2人は、何が簡単な式であるべきかを把握しようとしています。私は、列と行の可変数を持つことができるグリッドを持っています。ユーザーがセルの1つをクリックすると、col/rowに基づいてクリックされた「インデックス」を特定する必要があります。インデックスは0から始まり、左から右、次に上から下に移動します。固定列/行はありません。私が言いたいのグリッドの列/行の選択に基づいて項目インデックスを決定する数学

サンプル:3列、およびC2/R1上のユーザーがクリックがある場合は enter image description here

だから、それはすべてのインデックスが、この例では0から始まる5のインデックスを解決する必要があります。ここでは、

//I = Calculated index based on row/col (starts from 0) 
//ACol = Column index user clicked (starts from 0) 
//ARow = Row index user clicked (starts from 0) 
//ColCount = Number of columns 

I:= (C * ColCount) + (R - ColCount); 

EDIT参考

以下の私の全体の構成単位である:、遠くの作業からです

私の現在の式には、このようなものです。

式で行がコメント "HERE FORMULA" 以下の回答に

感謝を決議

unit ImageGrid; 

interface 

uses 
    Windows, Classes, SysUtils, Grids, Graphics, StdCtrls, ExtCtrls, Controls, 
    Jpeg, PngImage; 

type 
    TImageGrid = class; 
    TImageGridItem = class; 

    TGridSizing = (gsManual, gsAuto, gsFit); 

    TImageGridItem = class(TObject) 
    private 
    FFilename: TFilename; 
    FOwner: TImageGrid; 
    FBmp: TBitmap; 
    procedure Event; 
    procedure SetFilename(const Value: TFilename); 
    public 
    constructor Create(AOwner: TImageGrid); 
    destructor Destroy; override; 
    procedure LoadFile; 
    published 
    property Filename: TFilename read FFilename write SetFilename; 
    end; 

    TImageGrid = class(TCustomDrawGrid) 
    private 
    FItems: TStringList; 
    FCacheDir: String; 
    FRowHeight: Integer; 
    FColWidth: Integer; 
    FSizing: TGridSizing; 
    FItemIndex: Integer; 
    procedure SetCacheDir(const Value: String); 
    procedure SetColWidth(const Value: Integer); 
    procedure SetRowHeight(const Value: Integer); 
    procedure SetSizing(const Value: TGridSizing); 
    function GetItem(Index: Integer): TImageGridItem; 
    procedure SetItem(Index: Integer; const Value: TImageGridItem); 
    procedure SetItemIndex(const Value: Integer); 
    procedure SelectCell(Sender: TObject; ACol, ARow: Longint; 
     var CanSelect: Boolean); 
    protected 
    procedure Paint; override; 
    public 
    constructor Create(AOwner: TComponent); override; 
    destructor Destroy; override; 
    function Count: Integer; 
    property Items[Index: Integer]: TImageGridItem 
     read GetItem write SetItem; default; 
    function Add: TImageGridItem; 
    procedure Delete(const Index: Integer); 
    procedure Clear; 
    published 
    property CacheDir: String read FCacheDir write SetCacheDir; 
    property ColWidth: Integer read FColWidth write SetColWidth; 
    property RowHeight: Integer read FRowHeight write SetRowHeight; 
    property Sizing: TGridSizing read FSizing write SetSizing; 
    property ItemIndex: Integer read FItemIndex write SetItemIndex; 

    property Align; 
    property Anchors; 
    property BevelEdges; 
    property BevelInner; 
    property BevelKind; 
    property BevelOuter; 
    property BevelWidth; 
    property BiDiMode; 
    property BorderStyle; 
    property Color; 
    property ColCount; 
    property Constraints; 
    property Ctl3D; 
    property DefaultColWidth; 
    property DefaultRowHeight; 
    property DefaultDrawing; 
    property DoubleBuffered; 
    property DragCursor; 
    property DragKind; 
    property DragMode; 
    property DrawingStyle; 
    property Enabled; 
    property Font; 
    property GradientEndColor; 
    property GradientStartColor; 
    property GridLineWidth; 
    property Options; 
    property ParentBiDiMode; 
    property ParentColor; 
    property ParentCtl3D; 
    property ParentDoubleBuffered; 
    property ParentFont; 
    property ParentShowHint; 
    property PopupMenu; 
    property ScrollBars; 
    property ShowHint; 
    property TabOrder; 
    property Touch; 
    property Visible; 

    property OnClick; 
    property OnColumnMoved; 
    property OnContextPopup; 
    property OnDblClick; 
    property OnDragDrop; 
    property OnDragOver; 
    property OnDrawCell; 
    property OnEndDock; 
    property OnEndDrag; 
    property OnEnter; 
    property OnExit; 
    property OnGesture; 
    property OnGetEditMask; 
    property OnGetEditText; 
    property OnKeyDown; 
    property OnKeyPress; 
    property OnKeyUp; 
    property OnMouseActivate; 
    property OnMouseDown; 
    property OnMouseEnter; 
    property OnMouseLeave; 
    property OnMouseMove; 
    property OnMouseUp; 
    property OnMouseWheelDown; 
    property OnMouseWheelUp; 
    property OnRowMoved; 
    property OnSelectCell; 
    property OnSetEditText; 
    property OnStartDock; 
    property OnStartDrag; 
    property OnTopLeftChanged; 
    end; 

implementation 

//Register procedure will come later... 

{ TImageGrid } 

function TImageGrid.Add: TImageGridItem; 
begin 
    Result:= TImageGridItem.Create(Self); 
    FItems.AddObject('', Result); 
end; 

procedure TImageGrid.Clear; 
begin 
    while Count > 0 do 
    Delete(0); 
end; 

function TImageGrid.Count: Integer; 
begin 
    Result:= FItems.Count; 
end; 

constructor TImageGrid.Create(AOwner: TComponent); 
begin 
    inherited; 
    Options:= [goFixedVertLine,goFixedHorzLine,goVertLine,goHorzLine, 
    goRangeSelect,goThumbTracking]; 
    Parent:= TWinControl(AOwner); 
    FItems:= TStringList.Create; 
    FixedCols:= 0; 
    FixedRows:= 0; 
    RowCount:= 1; 
    ColCount:= 1; 
    FColWidth:= 100; 
    FRowHeight:= 100; 
    ColWidths[0]:= FColWidth; 
    RowHeights[0]:= FRowHeight; 
    FSizing:= gsManual; 
    FItemIndex:= -1; 
    OnSelectCell:= SelectCell; 

    Invalidate; 
end; 

procedure TImageGrid.Delete(const Index: Integer); 
begin 
    if (Index >= 0) and (Index < FItems.Count) then begin 
    TImageGridItem(FItems.Objects[Index]).Free; 
    FItems.Delete(Index); 
    end else begin 
    raise Exception.Create('List index out of bounds ('+IntToStr(Index)+')'); 
    end; 
end; 

destructor TImageGrid.Destroy; 
begin 
    FItems.Free; 
    inherited; 
end; 

function TImageGrid.GetItem(Index: Integer): TImageGridItem; 
begin 
    if (Index >= 0) and (Index < FItems.Count) then begin 
    Result:= TImageGridItem(FItems.Objects[Index]); 
    end else begin 
    Result:= nil; 
    raise Exception.Create('List index out of bounds ('+IntToStr(Index)+')'); 
    end; 
end; 

procedure TImageGrid.Paint; 
var 
    Bmp: TBitmap; 
    C: Integer; 
    RC: Integer; 
    CC: Integer; 
    X, Y: Integer; 
    I: TImageGridItem; 
    R: TRect; 

    procedure DrawImage(B: TBitmap; const R: TRect); 
    begin 
    Canvas.StretchDraw(R, B); 
    end; 

begin 
    Canvas.Brush.Style:= bsSolid; 
    Canvas.Pen.Style:= psClear; 
    Canvas.Brush.Color:= clWhite; 
    Canvas.FillRect(Canvas.ClipRect); 
    Bmp:= TBitmap.Create; 
    try 
    if Count > 0 then begin 
     case FSizing of 
     gsManual: begin 
      //Draw like regular grid with variable sizes - expand rows as needed 
      inherited; 

     end; 
     gsAuto: begin 
      //Calculate image width based on col count 

     end; 
     gsFit: begin 
      //Calculate col count based on image width 
      CC:= Trunc(ClientWidth/FColWidth); 
      RC:= Trunc(Count/CC); 
      ColCount:= CC; 
      RowCount:= RC; 
      for X := 0 to ColCount - 1 do 
      ColWidths[X]:= FColWidth; 
      for X := 0 to RowCount - 1 do 
      RowHeights[X]:= FRowHeight; 
      Canvas.Brush.Style:= bsSolid; 
      Canvas.Pen.Style:= psSolid; 
      Canvas.Brush.Color:= clWhite; 
      Canvas.Pen.Width:= 1; 
      C:= 0; //C = Count of items to show 
      for X := 0 to ColCount - 1 do begin 
      for Y := 0 to RowCount - 1 do begin 
       I:= Self.Items[C]; 
       if C = FItemIndex then begin 
       Canvas.Pen.Color:= clRed; 
       Canvas.Pen.Width:= 2; 
       end else begin 
       Canvas.Pen.Color:= clNavy; 
       Canvas.Pen.Width:= 1; 
       end; 
       R:= CellRect(X,Y); 
       Canvas.Rectangle(R); 
       InflateRect(R, -4, -4); 
       Canvas.StretchDraw(R, I.FBmp); 
       C:= C + 1; 
      end; 
      end; 
     end; 
     end; 
    end else begin 
     ColCount:= 1; 
     RowCount:= 1; 
    end; 
    finally 
    Bmp.Free; 
    end; 
end; 

procedure TImageGrid.SelectCell(Sender: TObject; ACol, ARow: Integer; 
    var CanSelect: Boolean); 
var 
    I: Integer; 
    C, R: Integer; 
begin 
    //Determine item index based on col/row 

    C:= ACol; 
    R:= ARow; 

    //I = Calculated index based on row/col (starts from 0) 
    //ACol = Column index user clicked (starts from 0) 
    //ARow = Row index user clicked (starts from 0) 
    //ColCount = Number of columns 

    I:= (R * ColCount) + C; //  <<----- FORMULA HERE 

    if I < Count - 1 then begin 
    FItemIndex:= I; 
    CanSelect:= True; 
    end else begin 
    FItemIndex:= -1; 
    CanSelect:= False; 
    end; 
    Invalidate; 
end; 

procedure TImageGrid.SetCacheDir(const Value: String); 
begin 
    if Value <> FCacheDir then begin 
    FCacheDir := Value; 
    Invalidate; 
    end; 
end; 

procedure TImageGrid.SetColWidth(const Value: Integer); 
begin 
    if Value <> FColWidth then begin 
    FColWidth := Value; 
    Invalidate; 
    end; 
end; 

procedure TImageGrid.SetItem(Index: Integer; const Value: TImageGridItem); 
begin 
    if (Index >= 0) and (Index < FItems.Count) then begin 
    FItems.Objects[Index]:= Value; 
    Invalidate; 
    end else begin 
    raise Exception.Create('List index out of bounds ('+IntToStr(Index)+')'); 
    end; 
end; 

procedure TImageGrid.SetItemIndex(const Value: Integer); 
begin 
    if Value <> FItemIndex then begin 
    FItemIndex := Value; 
    Invalidate; 
    end; 
end; 

procedure TImageGrid.SetRowHeight(const Value: Integer); 
begin 
    if Value <> FRowHeight then begin 
    FRowHeight := Value; 
    Invalidate; 
    end; 
end; 

procedure TImageGrid.SetSizing(const Value: TGridSizing); 
begin 
    if Value <> FSizing then begin 
    FSizing := Value; 
    Invalidate; 
    end; 
end; 

{ TImageGridItem } 

constructor TImageGridItem.Create(AOwner: TImageGrid); 
begin 
    FOwner:= AOwner; 
    FBmp:= TBitmap.Create; 
end; 

destructor TImageGridItem.Destroy; 
begin 
    FBmp.Free; 
    inherited; 
end; 

procedure TImageGridItem.Event; 
begin 
    FOwner.Invalidate; 
end; 

procedure TImageGridItem.LoadFile; 
    //Determine file type and load accordingly 
    function GetImage(const Filename: String; B: TBitmap): Bool; 
    var 
    E: String; 
    IJ: TJpegImage; 
    IP: TPngObject; 
    begin 
    Result:= False; 
    if FileExists(Filename) then begin 
     E:= UpperCase(ExtractFileExt(Filename)); 
     if E = '.BMP' then begin 
     B.LoadFromFile(Filename); 
     Result:= True; 
     end else 
     if (E = '.JPG') or (E = '.JPEG') then begin 
     IJ:= TJpegImage.Create; 
     try 
      IJ.LoadFromFile(Filename); 
      B.Assign(IJ); 
      Result:= True; 
     finally 
      IJ.Free; 
     end; 
     end else 
     if E = '.PNG' then begin 
     IP:= TPngObject.Create; 
     try 
      IP.LoadFromFile(Filename); 
      B.Assign(IP); 
      Result:= True; 
     finally 
      IP.Free; 
     end; 
     end else begin 
     raise Exception.Create('Invalid file extension ('+E+')'); 
     end; 
    end; 
    end; 

begin 
    GetImage(FFilename, FBmp); 
end; 

procedure TImageGridItem.SetFilename(const Value: TFilename); 
begin 
    if Value <> FFilename then begin 
    FFilename := Value; 
    LoadFile; 
    Event; 
    end; 
end; 

end. 

でマークされ、私はそれが固定してしまいました。最初は数式が間違っていると思っていましたが、コードのスコープを増やした後、別の場所では行と列が不適切にループしていました。以下は...それがどのように動作するかを

for Y := 0 to RowCount - 1 do begin 
    for X := 0 to ColCount - 1 do begin 

しかし、私が前にいたていたが...

for X := 0 to ColCount - 1 do begin 
    for Y := 0 to RowCount - 1 do begin 
+2

のインデックスを解決する必要がある場合は? –

+5

'(ARow * ColCount)+ ACol'についてはどうですか? @リーブン、あなたは私の心を読む。あなたは速かった、答えはあなたのものです:) – TLama

+5

@tlama - 私の秘密があります。今すぐ誰も私が自分自身で答えを出すことができないことを知っています:) –

答えて

16

次のトリックをあなたの例については

(R * ColCount) + C 

を行う必要があり、このうになります

(2 * 3) + 2 = 8 

...が3列あり、かつC2/R1をユーザーがクリックすると、それがどのように `(R * COLCOUNT)+ C`について5

(1 * 3) + 2 = 5 
+1

@リーブン:私はジョージにそれを帰属させます。返信して、正しいGeorgeを見つけようとしてくれてありがとう! –

+0

それは動作するようには表示されません...私はそれが少しで動作しなかった方法を説明する時間がかかります、現時点では十分な時間ではありません... –

+1

GOT IT。ダムの間違い。あなたの処方は完璧だった、ありがとう。しかし、私の塗装手順では、私は不適切に行/列をループしていた。それを切り替えて、それは動作します:D –

関連する問題