TImageList

From Free Pascal wiki
Jump to navigationJump to search

English (en) français (fr) русский (ru) 中文(中国大陆)‎ (zh_CN)

TImageList timagelist.png is a component that provides a list of images that can be shared between other components like TMainMenu/TMenuItem, TToolBar/TToolButton, TActionList, TBitBtn or TSpeedButton. All images have the same size as specified by the Width and Height property of TImageList. A component needing an image specifies this by means of its ImageIndex property.

Multiple-resolution TImageList in Lazarus 1.9 and newer

In Lazarus 1.9 the TImageList was rewritten to support multiple resolutions of one image.

ImageListEd-1.9.png

Every LCL control that supports an ImageList has now a new ImagesWidth property to decide what custom width at 96 PPI (100% scale) is to be used. Example: TToolBar.Images/ImageWidth, TListView.LargeImages/LargeImagesWidth.

Set the Scaled property to True and the image list will automatically pick up the scaled image in your High-DPI aware LCL application (provided that the option "Use LCL Scaling" has been checked in the project options).

Demo applications

There are 2 demo applications in Lazarus sources:

  • examples/imagelist_highdpi_designtime
  • examples/imagelist_highdpi_runtime

Changes affecting backwards compatibility

Add method

  • Old behavior: the image got sliced if too big or extended if too small.
  • New behavior: the image is scaled to all resolutions in the image list.
  • Reason: Image List now supports multiple resolutions.
  • Remedy: use AddSliced (if the image consists of several icons to be added) or AddSlice (if one image from a custom rect has to be added - also rect outside the image is supported).

How to create a multi-resolution ImageList in the application

  • In the first step you must tell the Imagelist which image sizes are needed.
    • Decide on the basic image size, usually 16x16. This is used at 96ppi screen resolution (in Windows: 100%).
    • If your application will also run at 144ppi (150%) or 192ppi (200%), it will also need images at 24x24 and 32x32 (24 = 150% of 16, 32 = 200% of 16).
    • In the case that some controls require a larger image size at 96pp, say 32x32, you should also prepare the imagelist for these scaled sizes, i.e. size 48 (=150% of 32) and 64 (=200% of 32) in this example.
  • Click on the New resolutions button and specify each of these extra sizes (only the width must be entered). The 16x16 size does not need to be added by the New resolutions button because it is already known from the Imagelist.Width and .Height properties.
  • In the next step you add the images themselves.
    • Click on the Add more resolutions button.
    • Navigate to the folder in which your images are stored (The png image format is highly recommended). Lazarus 2.3+, for example, has the images/general_purpose folder in its installation directory which is full of free png images designed for typical applications (thanks to Roland Hahn...). (svg master files can be found at https://sourceforge.net/p/lazarus-ccr/svn/HEAD/tree/image_sources/lazarus/images/general_purpose/).
    • Multi-select all sizes of the image that you want to load.
    • OK loads the images into the image list editor; missing sizes will be scaled down from larger sizes in surprisingly good quality.
    • Repeat with the other motives that you need.
    • Add only images that you need - they require a fairly large amount of memory.
    • If you wonder about the difference between the Add and Add more resolutions buttons: When you click Add only a single image can be selected, and the other sizes are extrapolated from it. Add more resolutions, on the other hand, allows multi-selection so that the individual images of the specific size can be selected.
    • The Replace and Replace all resolutions buttons allow to replace the image selected in the imagelist editor by another motif.
    • Delete removes all sizes of the image selected in the imagelist.
    • Clear erases the entire imagelist.
  • If you draw the images yourself, you may skip all the intermediate sizes. The minimum is to draw the largest images that you need; the smaller ones are scaled down automatically upon loading. However, the smallest image (16x16), sometimes also 24x24, appears a bit fuzzy; therefore, it is recommended to provide special versions of these sizes as well. It is maybe a good idea to draw the images in vector format (svg, using Inkscape) and to export to the needed size in png format.
  • Finally select the controls which require the non-standard default size and set their ImagesWidth to the corresponding value. In case of a TListView having a SmallImages and a LargeImages property, for example, set the LargeImagesWidth to 32; the SmallImagesWidth can stay at its default value, 0, because it is interpreted as the default size defined by the Imagelist.Width.
  • In order to activate automatic scaling of image sizes according to the current resolution of the monitor you must set the Scaled property of the Imagelist to true. Usually you should also provide a handler for the Imagelist event OnGetWidthForPPI to define that images should be scaled also for intermediate resolutions which were not added explictly in the "New resolutions" step above. (Otherwise only the next-smaller predefined image sizes will be used).
procedure TForm1.ImageList1GetWidthForPPI(Sender: TCustomImageList;
  AImageWidth, APPI: Integer; var AResultWidth: Integer);
begin
  AResultWidth := AImageWidth * APPI div 96;
end;

High-DPI alternative for Lazarus 1.8 and older: resize all images in TImageList

This is useful for example for High DPI scaling to get icons with higher resolution for TActionList, TMainMenu and TToolBar. Note: This may not work correctly with all widgetsets on all platforms. Note also: This code is not required for Laz 1.9+.

procedure ScaleImageList(ImgList: TImageList; NewWidth, NewHeight: Integer);
var
  TempImgList: TImageList;
  TempBmp1: TBitmap;
  TempBmp2: TBitmap;
  I: Integer;
begin
  TempImgList := TImageList.Create(nil);
  TempBmp1 := TBitmap.Create;
  TempBmp1.PixelFormat := pf32bit;
  TempBmp2 := TBitmap.Create;
  TempBmp2.PixelFormat := pf32bit;
  TempBmp2.SetSize(NewWidth, NewHeight);
  try
    TempImgList.Width := NewWidth;
    TempImgList.Height := NewHeight;

    for I := 0 to ImgList.Count - 1 do begin
      // Load image for given index to temporary bitmap
      ImgList.GetBitmap(I, TempBmp1);

      // Clear transparent image background
      TempBmp2.Canvas.Brush.Style := bsSolid;
      TempBmp2.Canvas.Brush.Color := TempBmp2.TransparentColor;
      TempBmp2.Canvas.FillRect(0, 0, TempBmp2.Width, TempBmp2.Height);

      // Stretch image to new size
      TempBmp2.Canvas.StretchDraw(Rect(0, 0, TempBmp2.Width, TempBmp2.Height), TempBmp1);
      TempImgList.Add(TempBmp2, nil);
    end;

    ImgList.Assign(TempImgList);
  finally
    TempImgList.Free;
    TempBmp1.Free;
    TempBmp2.Free;
  end;
end;

Example with ComboBox

To use TImageList, drop an TImageList object onto the form. In this example we need six images.

All images must be the same size. If two sizes of image are to be used, then two TImageLists must be used.

Set the height and width of the images in the Object Inspector; In this case 50px wide by 18px high.

Set Style to csOwnerDrawFixed.

Double-click on the TImageList icon to open the TImageList editor. Make sure that the icons show correctly when selected. If they are smaller than expected, check the size in the Object Inspector <F11>. You may have to reload the images.

ImageListEd.png

Place a ComboBox on the form and name it cbSymbols.

In the FormCreate event enter:

 cbSymbols.Items.Clear;
 for I := 0 to 5 do
   cbSymbols.Items.Add('');
 cbSymbols.ItemIndex := 0;

This will write 6 blank entries, and select the first.

In the OnDrawItem event for cbSymbols place the following code:

procedure TMyForm.cbSymbolsDrawItem( 
  aControl: TWinControl;
  iIndex: Integer; 
  aRect: TRect; 
  aState: TOwnerDrawState );
var
  cnv: TCanvas;
begin
  if not (aControl is TComboBox) then exit;
  cnv := TComboBox( aControl ).Canvas;
  Imagelist1.Draw( cnv, aRect.Left+2, aRect.Top+2, iIndex );
end;

The adjustments (+2) are to center the image in the item, if necessary.

combo.png

Example with SpeedButton

Add images to the ImageList1 like in the previous example and use:

   ImageList1.GetBitmap(iIndex,SpeedButton1.Glyph);

See also


LCL Components
Component Tab Components
Standard TMainMenu • TPopupMenu • TButton • TLabel • TEdit • TMemo • TToggleBox • TCheckBox • TRadioButton • TListBox • TComboBox • TScrollBar • TGroupBox • TRadioGroup • TCheckGroup • TPanel • TFrame • TActionList
Additional TBitBtn • TSpeedButton • TStaticText • TImage • TShape • TBevel • TPaintBox • TNotebook • TLabeledEdit • TSplitter • TTrayIcon • TControlBar • TFlowPanel • TMaskEdit • TCheckListBox • TScrollBox • TApplicationProperties • TStringGrid • TDrawGrid • TPairSplitter • TColorBox • TColorListBox • TValueListEditor
Common Controls TTrackBar • TProgressBar • TTreeView • TListView • TStatusBar • TToolBar • TCoolBar • TUpDown • TPageControl • TTabControl • THeaderControl • TImageList • TPopupNotifier • TDateTimePicker
Dialogs TOpenDialog • TSaveDialog • TSelectDirectoryDialog • TColorDialog • TFontDialog • TFindDialog • TReplaceDialog • TTaskDialog • TOpenPictureDialog • TSavePictureDialog • TCalendarDialog • TCalculatorDialog • TPrinterSetupDialog • TPrintDialog • TPageSetupDialog
Data Controls TDBNavigator • TDBText • TDBEdit • TDBMemo • TDBImage • TDBListBox • TDBLookupListBox • TDBComboBox • TDBLookupComboBox • TDBCheckBox • TDBRadioGroup • TDBCalendar • TDBGroupBox • TDBGrid • TDBDateTimePicker
Data Access TDataSource • TCSVDataSet • TSdfDataSet • TBufDataset • TFixedFormatDataSet • TDbf • TMemDataset
System TTimer • TIdleTimer • TLazComponentQueue • THTMLHelpDatabase • THTMLBrowserHelpViewer • TAsyncProcess • TProcessUTF8 • TProcess • TSimpleIPCClient • TSimpleIPCServer • TXMLConfig • TEventLog • TServiceManager • TCHMHelpDatabase • TLHelpConnector
Misc TColorButton • TSpinEdit • TFloatSpinEdit • TArrow • TCalendar • TEditButton • TFileNameEdit • TDirectoryEdit • TDateEdit • TTimeEdit • TCalcEdit • TFileListBox • TFilterComboBox • TComboBoxEx • TCheckComboBox • TButtonPanel • TShellTreeView • TShellListView • TXMLPropStorage • TINIPropStorage • TJSONPropStorage • TIDEDialogLayoutStorage • TMRUManager • TStrHolder
LazControls TCheckBoxThemed • TDividerBevel • TExtendedNotebook • TListFilterEdit • TListViewFilterEdit • TLvlGraphControl • TShortPathEdit • TSpinEditEx • TFloatSpinEditEx • TTreeFilterEdit • TExtendedTabControl •
RTTI TTIEdit • TTIComboBox • TTIButton • TTICheckBox • TTILabel • TTIGroupBox • TTIRadioGroup • TTICheckGroup • TTICheckListBox • TTIListBox • TTIMemo • TTICalendar • TTIImage • TTIFloatSpinEdit • TTISpinEdit • TTITrackBar • TTIProgressBar • TTIMaskEdit • TTIColorButton • TMultiPropertyLink • TTIPropertyGrid • TTIGrid
SQLdb TSQLQuery • TSQLTransaction • TSQLScript • TSQLConnector • TMSSQLConnection • TSybaseConnection • TPQConnection • TPQTEventMonitor • TOracleConnection • TODBCConnection • TMySQL40Connection • TMySQL41Connection • TMySQL50Connection • TMySQL51Connection • TMySQL55Connection • TMySQL56Connection • TMySQL57Connection • TSQLite3Connection • TIBConnection • TFBAdmin • TFBEventMonitor • TSQLDBLibraryLoader
Pascal Script TPSScript • TPSScriptDebugger • TPSDllPlugin • TPSImport_Classes • TPSImport_DateUtils • TPSImport_ComObj • TPSImport_DB • TPSImport_Forms • TPSImport_Controls • TPSImport_StdCtrls • TPSCustomPlugin
SynEdit TSynEdit • TSynCompletion • TSynAutoComplete • TSynMacroRecorder • TSynExporterHTML • TSynPluginSyncroEdit • TSynPasSyn • TSynFreePascalSyn • TSynCppSyn • TSynJavaSyn • TSynPerlSyn • TSynHTMLSyn • TSynXMLSyn • TSynLFMSyn • TSynDiffSyn • TSynUNIXShellScriptSyn • TSynCssSyn • TSynPHPSyn • TSynTeXSyn • TSynSQLSyn • TSynPythonSyn • TSynVBSyn • TSynAnySyn • TSynMultiSyn • TSynBatSyn • TSynIniSyn • TSynPoSyn
Chart TChart • TListChartSource • TRandomChartSource • TUserDefinedChartSource • TCalculatedChartSource • TDbChartSource • TChartToolset • TChartAxisTransformations • TChartStyles • TChartLegendPanel • TChartNavScrollBar • TChartNavPanel • TIntervalChartSource • TDateTimeIntervalChartSource • TChartListBox • TChartExtentLink • TChartImageList
IPro TIpFileDataProvider • TIpHtmlDataProvider • TIpHttpDataProvider • TIpHtmlPanel
Virtual Controls TVirtualDrawTree • TVirtualStringTree • TVTHeaderPopupMenu