Recent

Author Topic: [New Component] ExtTabCtrl - A custom, feature-rich tab control (LGPL)  (Read 568 times)

ovidio

  • New Member
  • *
  • Posts: 10
Compiled the demo projects at 96ppi and ran them at 144ppi - the inner dimensions scale correctly, fine!. With one exception: the images do not scale or are scaled by the system to become very pixelated - see screenshot.

Looking at the code of the demo_simple I see that you do not scale the user-provided imagelist. I set ImageList.Scaled to true, added two image resolutions for 24x24 and 32x32 images (in the ImageList editor) and replaced the icons by similar ones from the Lazarus icon collection (folder images/general_purpose). This changed the two user-icons on two tabs but left the internal icons for left/right arrows, close-crosses and add-tab unchanged. I guess these are the ButtonImages properties - but assigning some indices of my imagelist did not change anything. So, I am afraid that something's wrong here in image handling.

The other issue is that the user-provided images do not change their size when the projects runs under 144 ppi. You need some changes to take care of the "real" image size under High-DPI:

* In function TExtTabCtrl.GetTabImageWidth use FImages.WidthForPPI[0, Font.PixelsPerInch] to measure the image width; the "0" indicates that the default width of the images (i.a. at 96ppi) should be assumed to be the Width of the ImageList, but the images can be scaled to any other base width (normally there is an extra property "ImagesWidth" next to the "Images" property in controls using an ImageList). You may also have to apply the result of CanvasScaleFactor, but I don't have experience with it since Windows does not use it (macOS does...)

* Likewise, in GetTabImageHeight use FImages.HeightForPPI[...].

* I did not dive into your drawing code which is more complicated than usual because you are caching rotated images. But basically you should always call the XXXXForPPI methods of the imagelist to get the image at the correct size for the current resolution. Example: Draw the image of index AIndex at position AX, AY - AImageWidthAt96PPI is 0 (or FImagesWidth if you'd provide it), ATargetPPI is usually taken from the font settings (Font.PixelsPerInch), ACanvasFactor is the result of GetCanvasScaleFactor:
Code: Pascal  [Select][+][-]
  1. procedure DrawForPPI(ACanvas: TCanvas; AX, AY, AIndex: Integer;
  2.       AImageWidthAt96PPI, ATargetPPI: Integer; ACanvasFactor: Double; AEnabled: Boolean = True);

* In order to extract an image for caching you should call ImageList.ResolutionForPPI[AImageWidth, APPI: Integer; const ACanvasScaleFactor: Double].GetBitmap(Index: Integer; Image: TCustomBitmap)

In the attachment there's a version of demo_simple where everything should be set up for correct scaling.

Two more remarks:
* I am missing an imageindex entry for the close button in the ButtonImages property.
* You should declare all image index properties as TImageIndex rather than integer. Then the LCL can select the corresponding property editor which displays preview images in a combobox.

I have tried to implement all of your suggestions. I hope to have done it right (I have zero experience with high-DPI and don't have any setup to test it). I had a lot of troubles with GetCanvasScaleFactor (on my macOS it was returning 2, and this resulted in the image stretched to twice its size, extending outside the tab and pixelated), hence, I commented this out. Maybe somebody can tell me what was wrong.

Please, wp, can you give it a try?

ovidio

  • New Member
  • *
  • Posts: 10
I don't know, maybe there are similar one in the TabOptions property: When I turn toShowAddButton off in the Object inspector, the icon at the right does not disappear.
I believe that this behavior is because this image is on a TSpeedButton, and in edit mode components are shown even when Visible=False. Am I right?

Shouldn't the top stripe run across the entire width of the tab? And I am a bit confused about the colored line appearing above the top of the selected tab. Sometimes it is hard to be distinguished. Is it to highlight the selected tab again? Can it be turned off?
Yes, this "shadow" line is to highlight the selected tab (I have disabled it for the active tabs with a stripe color defined). Moreover, now the color stripe extends over all the tab. Can you check that it is OK?

ovidio

  • New Member
  • *
  • Posts: 10
I am a bit confused about the colored line appearing above the top of the selected tab. Sometimes it is hard to be distinguished. Is it to highlight the selected tab again? Can it be turned off?

I'm actually using PageControl combined with the component attabs for such purpose, but i did read this topic with interest.

My 5 pennies: a colored line appearing on top of the selected  a selected or hovered tab as well can be a very useful visual indicator resp. additional supporter to recognize better the selected tab and the tab where the mouse is actually over. Personally i won't miss such. See sample screenshots:

Right now, you can define a color stripe at the top of any tab, but the stripe remains visible even when the tab is not active. Only the Chrome style uses a stripe to indicate the active tab.

Indeed, the color stripes in ExtTabCtrl are inspired by ATTabs, which I have used in some projects. However, I found that ATTabs offers so many configuration options that I decided to create a component that is simpler for users to configure.

EDIT: You can easily get the same effect for any style, by setting/removing the StripeColor property when the tab is activated/deactivated.
« Last Edit: Today at 01:46:22 pm by ovidio »

ovidio

  • New Member
  • *
  • Posts: 10
In gtk3 there seems to be some text measuring issue
Was able to reproduce this outside the component and reported as a bug: https://gitlab.com/freepascal.org/lazarus/lazarus/-/work_items/42352

[EDIT]
Has been fixed already. Thank you, zeljko.

Great! Thank you!

 

TinyPortal © 2005-2018