unit ImageSelector; interface uses SysUtils, Classes, Controls, Graphics, ExtCtrls, Types, Dialogs; type TOnSelection = procedure ( sender:TObject; selectionindex:integer; filename:string ) of object; type TImageSelector = class(TGridPanel) type Directions = (ELeft, ERight, EUp, EDown); { directions to which the selection can move } private FSelectionBorder : integer; { The size of border line surrounding the current selection } FFilenames: TStrings; FImages : array of TPaintBox; FImageList : TImageList; FDirectionLeft: char; FDirectionRight: char; FDirectionDown: char; FDirectionUp: char; FDirectionPress: char; FSelected: integer; { index of current selection } FOnSelection: TOnSelection; FSelectionColor: TColor; procedure FImagePaint(Sender: TObject); procedure SetDirectionLeft(const Value: char); procedure SetDirectionRight(const Value: char); procedure SetDirectionDown(const Value: char); procedure SetDirectionUp(const Value: char); procedure SetDirectionPress(const Value: char); procedure SetSelected(const Value: integer); procedure SetSelectionColor(const Value: TColor); procedure Move(const dir:Directions); procedure SetFileNames(const Value: TStrings); protected procedure SetSelectionBorder(const Value: integer); virtual; public procedure Keypressed(const Key:char); constructor Create(AOwner:TComponent); override; destructor Destroy; override; published { published properties } property SelectionBorder:integer read FSelectionBorder write SetSelectionBorder default 4; property DirectionLeft:char read FDirectionLeft write SetDirectionLeft; property DirectionRight:char read FDirectionRight write SetDirectionRight; property DirectionUp:char read FDirectionUp write SetDirectionUp; property DirectionDown:char read FDirectionDown write SetDirectionDown; property DirectionPress:char read FDirectionPress write SetDirectionPress; property Selected:integer read FSelected write SetSelected default 0; property SelectionColour: TColor read FSelectionColor write SetSelectionColor default clRed; property Filenames: TStrings read FFileNames write SetFileNames; { properties for events } property OnSelection : TOnSelection read FOnSelection write FOnSelection; end; procedure Register; implementation constructor TImageSelector.Create(AOwner:TComponent); var image : TBitmap; i : integer; begin inherited Create(AOwner); { Call superclass constructor } SelectionColour := clRed; { set default selection colour to red as promised } SelectionBorder := 4; { set default selection border size to 4 as promised } Selected := 0; { set default selection index to 0 as promised } FFilenames := TStringList.Create; (*Ä for i:=0 to FFileNames.Count-1 do begin FImages[i] := TPaintBox.Create( self ); FImages[i].Parent := self; image := TBitmap.Create(); FImageList := TImageList.Create(self); image.LoadFromFile(Filenames[i]); FImages[i].Width := 80; FImages[i].Height := 80; FImageList.Width := 80; FImageList.Height := 80; FImageList.AddMasked(image,image.TransparentColor); image.Free; FImages[i].OnPaint := FImagePaint; { use same method for drawing all images } end; *) end; destructor TImageSelector.Destroy; begin FFilenames.Free; inherited; end; procedure TImageSelector.FImagePaint(Sender: TObject); var c:TCanvas; bmp : TBitMap; rd:TRect; i: integer; begin c := nil; for i:=0 to FFileNames.Count-1 do begin if ( Sender = FImages[i] ) then begin c := FImages[i].Canvas; break; end; end; if c = nil then exit; c := FImages[i].Canvas; bmp := TBitMap.Create; bmp.LoadFromFile(FFilenames[i]); // Oikeasti tämä pitää tehdä // "silmukan" ulkop. if selected = i then begin { fill the canvas with specified colour before drawing the image on top of it. this way we can indicate which is the selected image. } c.Brush.Color := SelectionColour; c.FloodFill(0,0, clRed, fsBorder); rd := Rect(SelectionBorder,SelectionBorder,bmp.Width-SelectionBorder,bmp.Height-SelectionBorder); end else begin { this image is not selected. Do not leave margin and fill the whole paintbox with the image. } rd := Rect(0,0,bmp.Width,bmp.Height); end; c.StretchDraw(rd,bmp); bmp.Free; end; procedure TImageSelector.Keypressed(const Key: char); begin /// VL: parempi hoitaa TActionListin avulla { this code left here for test purposes if (UpperCase(Key) = Uppercase(DirectionLeft)) then showmessage('left'); // something if (UpperCase(Key) = Uppercase(DirectionRight)) then showmessage('right'); if (UpperCase(Key) = Uppercase(DirectionUp)) then showmessage('up'); if (UpperCase(Key) = Uppercase(DirectionDown)) then showmessage('down'); if (UpperCase(Key) = Uppercase(DirectionPress)) then showmessage('press'); } if (UpperCase(Key) = Uppercase(DirectionLeft)) then Move(ELeft); if (UpperCase(Key) = Uppercase(DirectionRight)) then Move(ERight); if (UpperCase(Key) = Uppercase(DirectionUp)) then Move(EUp); if (UpperCase(Key) = Uppercase(DirectionDown)) then Move(EDown); if (UpperCase(Key) = Uppercase(DirectionPress)) then if Assigned(FOnSelection) then FOnSelection(self,selected,FFilenames[selected]); end; {------------------- Method for moving selection ------------------------------------} procedure TImageSelector.Move(const dir: Directions); var oldselection: integer; begin { store old selection } oldselection := selected; { calculate next selection based on pressed key Go through directions to find match for the Key. } if ( dir = ELeft ) then selected := selected-1; // something if ( dir = ERight) then selected := selected+1; if ( dir = EUp ) then selected := selected-ColumnCollection.Count; if ( dir = EDown ) then selected := selected+ColumnCollection.Count; { check that the selection index is still reasonable. } if (selected < 0) then begin selected := oldselection; end else if (selected > FFileNames.Count-1) then begin selected := FFileNames.Count-1; end; { force redraw } Invalidate; end; {-------------------- Property setter methods ------------------------------} procedure TImageSelector.SetDirectionDown(const Value: char); begin FDirectionDown := Value; end; procedure TImageSelector.SetDirectionLeft(const Value: char); begin FDirectionLeft := Value; end; procedure TImageSelector.SetDirectionPress(const Value: char); begin FDirectionPress := Value; end; procedure TImageSelector.SetDirectionRight(const Value: char); begin FDirectionRight := Value; end; procedure TImageSelector.SetDirectionUp(const Value: char); begin FDirectionUp := Value; end; procedure TImageSelector.SetFileNames(const Value: TStrings); var i: integer; image : TBitmap; begin { TODO: destroy previous entries } FFileNames.assign(Value); SetLength(FImages,Filenames.Count); for i := 0 to Filenames.Count - 1 do begin FImages[i] := TPaintBox.Create( self ); FImages[i].Parent := self; image := TBitmap.Create(); FImageList := TImageList.Create(self); image.LoadFromFile(Filenames[i]); FImages[i].Width := 80; FImages[i].Height := 80; FImageList.Width := 80; FImageList.Height := 80; FImageList.AddMasked(image,image.TransparentColor); image.Free; FImages[i].OnPaint := FImagePaint; { use same method for drawing all images } end; invalidate; end; procedure TImageSelector.SetSelected(const Value: integer); begin if (Value >= 0) or (value <= FFileNames.Count-1) then FSelected := Value; end; procedure TImageSelector.SetSelectionBorder(const Value: integer); begin FSelectionBorder := Value; end; procedure TImageSelector.SetSelectionColor(const Value: TColor); begin FSelectionColor := Value; end; {------------------ Property setter methods end----------------------------} {-------------------------- Register components----------------------------} procedure Register; begin RegisterComponents('Moposotacomponents', [TImageSelector]); end; {-------------------------- Register components----------------------------} end.