sptbxlib icon indicating copy to clipboard operation
sptbxlib copied to clipboard

Add support for TSVGIconImageList

Open skamradt opened this issue 2 years ago • 7 comments

One of the SVG options that is available via GetIt in the more recent versions of Delphi contains the TSVGIconImageList. Using this list for SVG images mostly works, however the disabled drawing is broken, which is extremely visible if you use a dark theme. I made the following changes to TB2Common in the SpIsVirtualImageList procedure. The code change is towards the bottom of this procedure. I believe the patch file would need to be updated to include this change.

    // special case for TSVGIconImageList (also uses RTTI)
    else
      if (ImageList.ClassName = 'TSVGIconImageList') then begin
        if enabled then
          ImageList.Draw(ACanvas, ARect.Left, ARect.Top, ImageIndex)
        else
          begin
            RttiC := TRttiContext.Create;
            // Paint disabled
            RTTIC.GetType(ImageList.ClassType).GetMethod('PaintTo').Invoke(
              ImageList,[ACanvas,ImageIndex,ARect.Left,ARect.Top,ARect.Width,aRect.Height,False]);
          end;
      end
    else
   // end special case
    {$IFEND}
     // For older versions of Delphi

skamradt avatar Nov 24 '23 14:11 skamradt

Strange. I use TSVGIconImageList and the disabled images painting looks fine without your patch.

image

pyscripter avatar Nov 24 '23 15:11 pyscripter

it works fine if the colors (in your example) are white and your using a dark background. My source images are black and I am toggling between light and dark themes. So, on my almost black theme, when it falls back to the source color (which is black) and then draws that...which results in the following: image then with my change: image

This also gives you control over how the disabled items draw by modifying the properties on the TSVGIconImageList for DisabledGreyScale (mine set to false) and DisabledOpacity (mine set to 50). I am setting FixedColor to match that of the theme clButtonText when I load a theme which simplifies having to have multiple sets of icons for my toolbar.

skamradt avatar Nov 24 '23 16:11 skamradt

My source images are black and I am toggling between light and dark themes.

The point with Svgs is that you can adjust the color to match the theme.

Here is how my toolbar looks on a light background: image

and here is some code to do that every time the Vcl Style changes:

procedure TResourcesDataModule.UpdateImageCollections;

  procedure ProcessImageCollection(IC: TSVGIconImageCollection;
    FixedColor: TColor; AntiAliasColor: TColor = TColors.SysDefault);
  begin
    IC.SVGIconItems.BeginUpdate;
    try
      IC.FixedColor := SvgFixedColor(FixedColor);

      if AntiAliasColor <> TColors.SysDefault then
        IC.AntiAliasColor := StyleServices.GetSystemColor(AntiAliasColor);
    finally
      IC.SVGIconItems.EndUpdate;
    end;
  end;

var
  TextColor: TColor;
begin
  var Details := StyleServices.GetElementDetails(ttbButtonNormal);
  if not StyleServices.GetElementColor(Details, ecTextColor, TextColor) then
    TextColor := StyleServices.GetSystemColor(TColors.SysBtnText);

  ProcessImageCollection(icBrowserImages, TextColor);
  ProcessImageCollection(icCodeImages, TColors.SysWindowText, TColors.SysWindow);
  ProcessImageCollection(icGutterGlyphs, TextColor);
  ProcessImageCollection(icSVGImages, TextColor);
end;

pyscripter avatar Nov 24 '23 16:11 pyscripter

Odd, I am performing pretty much the same changes to the image list:

PanelColor := ComputePanelColor; // slightly lighter on dark themes, darker on light themes
ToolbarColor := ColorBlendRGB(StyleServices.GetSystemColor(clBtnFace),PanelColor,0.5);
  :
TSVGIconImageList(lCtrl).FixedColor := StyleServices.GetSystemColor(clBtnText);
TSVGIconImageList(lCtrl).AntiAliasColor := ToolbarColor;

skamradt avatar Nov 24 '23 17:11 skamradt

What are your VirtualImageList options? image

If your icons are white on a dark background, which apparently they are, then drawing with opacity should work.

pyscripter avatar Nov 24 '23 17:11 pyscripter

I'm not using a virtual image list. I am using the TSVGIconImageList directly. This is on Delphi 12 (application is being updated from Delphi 10.3)

skamradt avatar Nov 24 '23 17:11 skamradt

Which version of Delphi are you on?

I'm not using a virtual image list. I am using the TSVGIconImageList directly.

TSVGIconImageList is only for old versions of Delphi before Tokyo.

pyscripter avatar Nov 24 '23 17:11 pyscripter