Table of Contents

Bitmap Selection

TTMSFNCBitmapPicker and TTMSFNCBitmapSelector let users select an image from a grid of bitmaps. The picker opens the grid in a drop-down popup; the selector embeds the grid directly on the form.

TTMSFNCBitmapSelector

Bitmap Picker

Populate Items

Items can reference a bitmap by name from a shared TTMSFNCBitmapContainer, or carry their own Bitmap property. Using a container keeps images reusable across controls.

procedure TForm1.ConfigureBitmapPicker;
var
  Item: TTMSFNCBitmapSelectorItem;
begin
  TMSFNCBitmapPicker1.BitmapContainer := TMSFNCBitmapContainer1;

  Item := TMSFNCBitmapPicker1.Items.Add;
  Item.BitmapName := 'status-ok';

  Item := TMSFNCBitmapPicker1.Items.Add;
  Item.BitmapName := 'status-warning';

  TMSFNCBitmapPicker1.SelectedItemIndex := 0;
end;

Read the Selection

Use SelectedItemIndex when the item position matters, or SelectedBitmap when you need the image instance directly.

procedure TForm1.ApplySelectedBitmap;
begin
  TMSFNCImage1.Bitmap.Assign(TMSFNCBitmapPicker1.SelectedBitmap);
  Caption := 'Selected item: ' + TMSFNCBitmapPicker1.SelectedItemIndex.ToString;
end;

FindItemByBitmap and FindBitmapByItem help map between index and bitmap when the selection is driven programmatically.


Bitmap Selector

TTMSFNCBitmapSelector is the standalone grid that the picker wraps. Drop it directly onto a form when a persistent visual palette is more appropriate than a drop-down.

Columns and Rows control the grid shape. Each item supports Bitmap, BitmapName (shared container), ColSpan, RowSpan, Hidden, and Disabled.

Custom Drawing

Override OnItemAfterDrawContent to replace the default rendering per item based on its current state (isNormal, isHover, isDown, isSelected).

procedure TForm1.ConfigureBitmapSelector;
var
  I: Integer;
begin
  TMSFNCBitmapSelector1.BeginUpdate;
  TMSFNCBitmapSelector1.Items.Clear;
  TMSFNCBitmapSelector1.Columns := 3;
  TMSFNCBitmapSelector1.Rows := 1;
  for I := 0 to 2 do
    TMSFNCBitmapSelector1.Items.Add;
  TMSFNCBitmapSelector1.EndUpdate;
end;

procedure TForm1.TMSFNCBitmapSelector1BitmapSelect(Sender: TObject;
  AItemIndex: Integer; ABitmap: TTMSFNCBitmap);
begin
  Caption := 'Selected index: ' + AItemIndex.ToString;
end;

procedure TForm1.TMSFNCBitmapSelector1ItemAfterDrawContent(Sender: TObject;
  AGraphics: TTMSFNCGraphics; ARect: TRectF; AItemIndex: Integer);
var
  pt: TTMSFNCGraphicsPath;
begin
  case TMSFNCBitmapSelector1.Items[AItemIndex].State of
    isHover: InflateRect(ARect, -4, -4);
    isDown, isSelected:
    begin
      InflateRectEx(ARect, -4, -4);
      AGraphics.Stroke.Width := 2;
      AGraphics.Stroke.Color := gcBlack;
    end;
    isNormal: InflateRectEx(ARect, -8, -8);
  end;
  ARect := RectF(Int(ARect.Left) + 0.5, Int(ARect.Top) + 0.5,
    Int(ARect.Right) + 0.5, Int(ARect.Bottom) + 0.5);
  case AItemIndex of
    0: begin AGraphics.Fill.Color := gcBlue;  AGraphics.DrawEllipse(ARect); end;
    1: begin AGraphics.Fill.Color := gcGreen; AGraphics.DrawRectangle(ARect); end;
    2:
    begin
      pt := TTMSFNCGraphicsPath.Create;
      pt.MoveTo(PointF(ARect.Left + ARect.Width / 2, ARect.Top));
      pt.LineTo(PointF(ARect.Right, ARect.Bottom));
      pt.LineTo(PointF(ARect.Left,  ARect.Bottom));
      pt.ClosePath;
      AGraphics.Fill.Color := gcRed;
      AGraphics.DrawPath(pt);
      pt.Free;
    end;
  end;
end;
TTMSFNCBitmapSelector with custom-drawn shapes