में कॉल/पंक्ति चयन के आधार पर आइटम इंडेक्स निर्धारित करने के लिए मठ मुझे और 2 लोग यह पता लगाने की कोशिश कर रहे हैं कि एक सरल सूत्र क्या होना चाहिए। मेरे पास एक ग्रिड है, जिसमें कॉलम और पंक्तियों की एक चर संख्या हो सकती है। जब उपयोगकर्ता कोशिकाओं में से किसी एक पर क्लिक करता है, तो मुझे यह निर्धारित करना होगा कि कॉल/पंक्ति के आधार पर कौन सा 'अनुक्रमणिका' क्लिक किया गया था। इंडेक्स 0 से शुरू होते हैं और बाएं से दाएं जाते हैं, फिर ऊपर से नीचे। कोई निश्चित कॉल/पंक्तियां नहीं हैं।ग्रिड
मैं क्या मतलब का नमूना:
तो अगर वहाँ 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
के सूचकांक को हल करने की जरूरत है? –
'(तीर * ColCount) + ACol' के बारे में क्या? @ लिवन, तुमने मेरा दिमाग पढ़ा; आप तेज़ थे, जवाब तुम्हारा है :) – TLama
@TLama - मेरा रहस्य बाहर है। अब सभी जानते हैं कि मैं खुद के जवाब के साथ नहीं आ सकता :) :) –