2012-01-15 39 views
6

में कॉल/पंक्ति चयन के आधार पर आइटम इंडेक्स निर्धारित करने के लिए मठ मुझे और 2 लोग यह पता लगाने की कोशिश कर रहे हैं कि एक सरल सूत्र क्या होना चाहिए। मेरे पास एक ग्रिड है, जिसमें कॉलम और पंक्तियों की एक चर संख्या हो सकती है। जब उपयोगकर्ता कोशिकाओं में से किसी एक पर क्लिक करता है, तो मुझे यह निर्धारित करना होगा कि कॉल/पंक्ति के आधार पर कौन सा 'अनुक्रमणिका' क्लिक किया गया था। इंडेक्स 0 से शुरू होते हैं और बाएं से दाएं जाते हैं, फिर ऊपर से नीचे। कोई निश्चित कॉल/पंक्तियां नहीं हैं।ग्रिड

मैं क्या मतलब का नमूना: enter image description here

तो अगर वहाँ 3 कॉलम, और सी 2/R1 पर उपयोगकर्ता क्लिक कर रहे हैं, तो यह की जरूरत है 5. के सूचकांक सभी अनुक्रमित इस उदाहरण में 0 से शुरू हल करने ।

मेरे वर्तमान सूत्र है, जो काम कर रहा से दूर है, इस तरह है:

//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); 

संपादित

संदर्भ के लिए, नीचे अपने पूरे घटक इकाई है।

फार्मूले के साथ लाइन एक टिप्पणी "सूत्र यहाँ"

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

'(तीर * ColCount) + ACol' के बारे में क्या? @ लिवन, तुमने मेरा दिमाग पढ़ा; आप तेज़ थे, जवाब तुम्हारा है :) – TLama

+5

@TLama - मेरा रहस्य बाहर है। अब सभी जानते हैं कि मैं खुद के जवाब के साथ नहीं आ सकता :) :) –

उत्तर

16

अपने उदाहरणों के लिए चाल

(R * ColCount) + C 

करना चाहिए के बाद, यह होगा

(2 * 3) + 2 = 8 

और ... अगर वहाँ 3 कॉलम दिए गए हैं, और सी 2/R1 पर उपयोगकर्ता क्लिक करता है, तो यह कैसे के बारे में `(आर * ColCount) + C` 5

(1 * 3) + 2 = 5 
+1

@Lieven: मैं इसे जॉर्ज के लिए जिम्मेदार ठहराऊंगा। उत्तर देने के लिए धन्यवाद और सही जॉर्ज खोजने की कोशिश! –

+0

यह काम नहीं करता है ... मैं समझाने के लिए समय लेगा कि यह थोड़ा सा काम नहीं करता है, इस समय पर्याप्त समय नहीं है ... –

+1

इसे प्राप्त करें। गूंगा गलती आपका फॉर्मूला सही था, धन्यवाद। लेकिन मेरी पेंट प्रक्रिया में, मैं पंक्तियों/स्तंभों के माध्यम से अनुचित रूप से लूपिंग कर रहा था। इसे चारों ओर स्विच किया और यह काम करता है: डी –