2

I was looking for a custom image grid and found a similar question that had a really sweet component in an answer.

I downloaded the code and after some fiddling, I managed to get it to compile in DXE2. It looks really cool, but I can't get either scrollbar to show up. I also can't figure out how to dynamically control the images displayed. Or how to update the grid based on keyboard events.

Also, to get it to compile I had to remove the GR32 references; the library I downloaded had too many incompatibilities with DXE2 for me to resolve.

Any help would be greatly appreciated. This really looks like a killer component.

Update from Bill:

Here is a screenshot of incorrect thumbnail painting. I can not get the thumbnails to look like the screenshot from the component in question.

Thumbnail Painting of ImageGrid

If the thumbnails were painted at the same XY as the rects painted in the first pass they would look much better. Any idea on what is going on?

Community
  • 1
  • 1
skippix
  • 481
  • 1
  • 6
  • 14
  • I assume you mean the component from [this answer](http://stackoverflow.com/a/8954813/757830) and I am the author. What exactly are you missing? The horizontal scrollbar is missing by design and the vertical scrollbar appears when there are more images loaded then can be shown by setting `ColWidth` and `RowHeight`. Currently, you can scroll the control by key strokes, what more keyboard events are you looking for? And what do you mean by "dynamically control the images displayed"? – NGLN Mar 27 '12 at 05:23
  • 1
    On removing GR32 references: setting `{.$DEFINE GR32}` would have been enough. ;) – NGLN Mar 27 '12 at 05:56
  • Thanks for your help! First, to get it to compile in DXE2, I: removed {.$DEFINE GR32} ;-) from ImageGrid.pas replaced vcljpg with vclimg in ImageGrid70.dpk After building the package and installing the component, I created a new project and dropped the component on the form. The only property assignment was to the folder property, assigning a folder with images. When I run the it, the default 6 images show, but no scrollbar or keyboard navigation. "Dynamically control the images displayed": manually load a stringlist of filenames (if you want to use btns to navigate). I got this working. – skippix Mar 27 '12 at 12:36
  • I tried this component in Delphi 2010 and also found the vertical scrollbar is not visible. The component paints a rect in the first pass then fills the rect with the thumbnail, but the thumbnail is painted in a different XY then painted in the first pass. This seems to be a nice component and threading works nicely, but no vertical scrollbar and wrong thumbnail painting.... at least in my copy. I added VertScrollBar.Range := FRowCount * (FRowHeight + FImageSpacing) to procedure TImageGrid.RearrangeImages;and now the vertical scrollbar appears but I am not sure if my code is correct. – Bill Mar 27 '12 at 15:30
  • Please expand on "wrong thumbnail painting", @Bill. I update a label caption in the OnClick event and am getting the correct images. However, I do experience some inconsistency in that sometimes the thumbnail is blank. If I force a refresh (I'm using buttons to navigate, resetting the filenames on the button click), I can get all the images to show up. – skippix Mar 27 '12 at 15:43
  • @Bill: try playing with the ColWidth and RowHeight values, as well as the general grid width and height. The native image aspect ratio depends on the camera; standard is 3:2 for DSLRs, but 5:4 for many point-and-shoots. I have mine set to ColWidth = 240 and RowHeight = 160 and they look fine (when they all show up...) – skippix Mar 27 '12 at 16:24
  • @NGLN, you should really version value to that component! I have missed the latest update :) – kobik Mar 27 '12 at 16:26
  • @skippix: I set the ColWidth to 128 and RowHeight to 96 and the thumbnails are painted better now... but shouldn't the component work with any size (within reason) work correctly? Changing the thumbnail dimensions also seems problematic as well as the results are not what you would expect. Did my fix make your vertical scrollbar appear for you? – Bill Mar 27 '12 at 16:31
  • 1
    @kobik Yeah, I will add it to my repository soon. A whole bunch of SO-comps I might add... ;) – NGLN Mar 27 '12 at 16:44
  • @NGLN, It would be nice to add selection to it, and then it will be awesome! ;) – kobik Mar 27 '12 at 17:05
  • 1
    @kobik The [component](http://stackoverflow.com/a/8954813/757830) is completely rewritten and made [OpenSource](https://svn.apada.nl/svn/NLDelphi-opensource/ngln/AwImageGrid/). – NGLN May 12 '13 at 09:23
  • @NGLN, Thanks! Do you support D5 also? – kobik May 12 '13 at 09:48

1 Answers1

1

... but I can't get either scrollbar to show up.

Well, there is no horizontal scrollbar. There is the property ColWidth that controls how much images are drawn in one row, depending on the control's width. You might update ColWidth in an OnResize event handler due to anchor settings, for example.

The vertical scroll bar appears automatically when not all images (incl. spacing) fit in the clientrect. The images are drawn on a TPaintBox and that paint box' size is updated as soon as the image count changes:

procedure TImageGrid.RearrangeImages;
begin
  ...
    FPainter.Height := Max(ClientHeight,
      FRowCount * (FRowHeight + FImageSpacing) - FImageSpacing);

The component inherites from TScrollingWinControl, so the scroll bar should modify accordingly. If not, then Bill has a workaround found as commented:

VertScrollBar.Range := FRowCount * (FRowHeight + FImageSpacing) - FImageSpacing;

I understand this obviously also works, but I really wonder why the scroll bar's range should be modified manually. Here in D7 I have no problem with a hidden vertical scroll bar.

... I also can't figure out how to dynamically control the images displayed. ...

The most easy way to fill the component is by assigning the Folder property to a path with images. Only the images with the file formats in the FileFormats property will be loaded. To specify the images manually (e.g. to combine multiple folders), use the FileNames property. When the Folder property is set, then the FileNames property is updated accordingly, but those file names are not stored in the DFM. When you change the file names (e.g. you delete one from the folder), then the Folder property is cleared and the component uses the FileNames property instead.

... Or how to update the grid based on keyboard events. ...

The only keystrokes currently implemented are Up, Down, PageUp, PageDown, Home and End which all scroll the control. What more key actions do you wish? It's a viewer.

Here is a screenshot of incorrect thumbnail painting. I can not get the thumbnails to look like the screenshot from the component in question. ... If the thumbnails were painted at the same XY as the rects painted in the first pass they would look much better.

While loading the images, a temporary rect is drawn with size ColWidth * RowHeight. All images are stretchdrawn within that size, so adjust your ratio of these properties to make the spacing equal everywhere. Note that you can also influence appearance with the ImageHorzAlign and ImageVertAlign properties.

Update:

The component you refer to is recently completely rewritten, and some of the answers above are outdated.

It now has a Propertional property that defaults to True, but when set False, it will stretch up the thumbs to whatever cell size you have set, independent from the original image sizes. Small images could remain narow though, unless you set the new Stretch property to True.

It now distinguishes between RowHeight and CellHeight, and ColWidth and CellWidth. The difference between both is CellSpacing.

The component does not descend from TScrollingWinControl anymore, but from TCustomControl and only the vertical scroll bar is added.

Community
  • 1
  • 1
NGLN
  • 43,011
  • 8
  • 105
  • 200
  • @NGLN- Should ReloadImages be made public so you can change the thumbnail dimensions at runtime? SetImageSize(156, 80); ColWidth := 156; RowHeight := 80; ReloadImages; Should SetImageSize or should ColWidth and RowHeight be used? – Bill Mar 27 '12 at 16:49
  • @Bill No. `SetImageSize` is already public and calls `ReloadImages`. `ColWidth` and `RowHeight` both invoke `SetImageSize`. You _have to_ use `SetImageSize` when both sizes change, otherwise you _may_ choose which to use. – NGLN Mar 27 '12 at 16:54
  • @NGLN- But, when I call SetImageSize here the thumbnails are not reloaded...? so I made ReloadImages public and that refreshes the thumbnails now. – Bill Mar 27 '12 at 17:05
  • @Bill Then you have not given other dimensions. Why would you want to reload the images then anyway? – NGLN Mar 27 '12 at 17:09
  • @NGLN- Ok... my mistake... SetImageSize is working now for some reason... I only wanted to reload because when I first tried it the thumbnails were not refreshed. I do see some empty thumbnails on ocassion too. Do you have a website? – Bill Mar 27 '12 at 17:12
  • It seems as though there shoud be a MaintainAspectRatio property because if the aspect is incorrect then the thumbnails are painted incorrectly and this may be causing the ocassional empty thumbnails as well? – Bill Mar 27 '12 at 17:19
  • BINGO! adding that line of code to RearrangeImages seems to have cleared up all my issues. For whatever reason, with the absence of the scrollbar, there were no keyboard events. All of my thumbs are showing up now, as well. – skippix Mar 27 '12 at 17:29