Browse Source

Added PNG and BMP to FormatUI; Added test for FormatUI;

Added PNG and BMP to FormatUI;
Added test for FormatUI;
Massimo Magnano 8 months ago
parent
commit
3f18ea919c

+ 197 - 8
bgraformatui.lfm

@@ -1,13 +1,13 @@
 object BGRAFormatUIContainer: TBGRAFormatUIContainer
 object BGRAFormatUIContainer: TBGRAFormatUIContainer
   Left = 374
   Left = 374
-  Height = 355
+  Height = 530
   Top = 34
   Top = 34
   Width = 713
   Width = 713
   Caption = 'BGRAFormatUIContainer'
   Caption = 'BGRAFormatUIContainer'
-  ClientHeight = 355
+  ClientHeight = 530
   ClientWidth = 713
   ClientWidth = 713
   DesignTimePPI = 120
   DesignTimePPI = 120
-  LCLVersion = '4.99.0.0'
+  OnCreate = FormCreate
   object ifJpeg: TBCPanel
   object ifJpeg: TBCPanel
     Left = 0
     Left = 0
     Height = 150
     Height = 150
@@ -50,13 +50,13 @@ object BGRAFormatUIContainer: TBGRAFormatUIContainer
     object ifJpeg_GrayScale: TCheckBox
     object ifJpeg_GrayScale: TCheckBox
       Left = 16
       Left = 16
       Height = 24
       Height = 24
-      Top = 9
+      Top = 8
       Width = 90
       Width = 90
       Caption = 'Gray Scale'
       Caption = 'Gray Scale'
       TabOrder = 0
       TabOrder = 0
     end
     end
     object ifJpeg_ProgressiveEncoding: TCheckBox
     object ifJpeg_ProgressiveEncoding: TCheckBox
-      Left = 18
+      Left = 16
       Height = 24
       Height = 24
       Top = 40
       Top = 40
       Width = 162
       Width = 162
@@ -149,7 +149,7 @@ object BGRAFormatUIContainer: TBGRAFormatUIContainer
   object panelButtons: TPanel
   object panelButtons: TPanel
     Left = 0
     Left = 0
     Height = 50
     Height = 50
-    Top = 305
+    Top = 480
     Width = 713
     Width = 713
     Align = alBottom
     Align = alBottom
     BevelOuter = bvSpace
     BevelOuter = bvSpace
@@ -221,13 +221,13 @@ object BGRAFormatUIContainer: TBGRAFormatUIContainer
     object ifTiff_SaveCMYKAsRGB: TCheckBox
     object ifTiff_SaveCMYKAsRGB: TCheckBox
       Left = 16
       Left = 16
       Height = 24
       Height = 24
-      Top = 9
+      Top = 8
       Width = 147
       Width = 147
       Caption = 'Save CMYK As RGB'
       Caption = 'Save CMYK As RGB'
       TabOrder = 0
       TabOrder = 0
     end
     end
     object ifTiff_PremultiplyRGB: TCheckBox
     object ifTiff_PremultiplyRGB: TCheckBox
-      Left = 18
+      Left = 16
       Height = 24
       Height = 24
       Top = 40
       Top = 40
       Width = 128
       Width = 128
@@ -235,4 +235,193 @@ object BGRAFormatUIContainer: TBGRAFormatUIContainer
       TabOrder = 1
       TabOrder = 1
     end
     end
   end
   end
+  object ifPng: TBCPanel
+    Left = 0
+    Height = 170
+    Top = 152
+    Width = 350
+    Background.Color = clBtnFace
+    Background.Gradient1.StartColor = clWhite
+    Background.Gradient1.EndColor = clBlack
+    Background.Gradient1.GradientType = gtLinear
+    Background.Gradient1.Point1XPercent = 0
+    Background.Gradient1.Point1YPercent = 0
+    Background.Gradient1.Point2XPercent = 0
+    Background.Gradient1.Point2YPercent = 100
+    Background.Gradient2.StartColor = clWhite
+    Background.Gradient2.EndColor = clBlack
+    Background.Gradient2.GradientType = gtLinear
+    Background.Gradient2.Point1XPercent = 0
+    Background.Gradient2.Point1YPercent = 0
+    Background.Gradient2.Point2XPercent = 0
+    Background.Gradient2.Point2YPercent = 100
+    Background.Gradient1EndPercent = 35
+    Background.Style = bbsColor
+    BevelInner = bvNone
+    BevelOuter = bvRaised
+    BevelWidth = 1
+    Border.Style = bboNone
+    Caption = 'jfPng'
+    FontEx.Color = clDefault
+    FontEx.FontQuality = fqSystemClearType
+    FontEx.Shadow = False
+    FontEx.ShadowRadius = 5
+    FontEx.ShadowOffsetX = 5
+    FontEx.ShadowOffsetY = 5
+    FontEx.Style = []
+    ParentBackground = False
+    Rounding.RoundX = 1
+    Rounding.RoundY = 1
+    TabOrder = 3
+    Visible = False
+    object ifPng_GrayScale: TCheckBox
+      Left = 16
+      Height = 24
+      Top = 8
+      Width = 90
+      Caption = 'Gray Scale'
+      TabOrder = 0
+    end
+    object ifPng_WordSized: TCheckBox
+      Left = 16
+      Height = 24
+      Top = 40
+      Width = 98
+      Caption = 'Word Sized'
+      TabOrder = 1
+    end
+    object Label2: TLabel
+      Left = 18
+      Height = 20
+      Top = 74
+      Width = 124
+      Caption = 'Compression Level'
+    end
+    object ifPng_CompressionLevel: TBCFluentSlider
+      Left = 32
+      Height = 40
+      Top = 96
+      Width = 300
+      MaxValue = 3
+      Value = 2
+      ShowTicks = True
+      TickFrequency = 1
+    end
+    object Label3: TLabel
+      Left = 28
+      Height = 20
+      Top = 135
+      Width = 36
+      Alignment = taCenter
+      Caption = 'None'
+    end
+    object Label4: TLabel
+      Left = 124
+      Height = 20
+      Top = 135
+      Width = 25
+      Alignment = taCenter
+      Caption = 'Fast'
+    end
+    object Label5: TLabel
+      Left = 204
+      Height = 20
+      Top = 136
+      Width = 49
+      Alignment = taCenter
+      Caption = 'Default'
+    end
+    object Label6: TLabel
+      Left = 304
+      Height = 20
+      Top = 136
+      Width = 28
+      Alignment = taCenter
+      Caption = 'Max'
+    end
+  end
+  object ifBmp: TBCPanel
+    Left = 352
+    Height = 150
+    Top = 152
+    Width = 350
+    Background.Color = clBtnFace
+    Background.Gradient1.StartColor = clWhite
+    Background.Gradient1.EndColor = clBlack
+    Background.Gradient1.GradientType = gtLinear
+    Background.Gradient1.Point1XPercent = 0
+    Background.Gradient1.Point1YPercent = 0
+    Background.Gradient1.Point2XPercent = 0
+    Background.Gradient1.Point2YPercent = 100
+    Background.Gradient2.StartColor = clWhite
+    Background.Gradient2.EndColor = clBlack
+    Background.Gradient2.GradientType = gtLinear
+    Background.Gradient2.Point1XPercent = 0
+    Background.Gradient2.Point1YPercent = 0
+    Background.Gradient2.Point2XPercent = 0
+    Background.Gradient2.Point2YPercent = 100
+    Background.Gradient1EndPercent = 35
+    Background.Style = bbsColor
+    BevelInner = bvNone
+    BevelOuter = bvRaised
+    BevelWidth = 1
+    Border.Style = bboNone
+    Caption = 'ifBmp'
+    FontEx.Color = clDefault
+    FontEx.FontQuality = fqSystemClearType
+    FontEx.Shadow = False
+    FontEx.ShadowRadius = 5
+    FontEx.ShadowOffsetX = 5
+    FontEx.ShadowOffsetY = 5
+    FontEx.Style = []
+    ParentBackground = False
+    Rounding.RoundX = 1
+    Rounding.RoundY = 1
+    TabOrder = 4
+    Visible = False
+    object ifBmp_RLECompress: TCheckBox
+      Left = 16
+      Height = 24
+      Top = 76
+      Width = 135
+      Caption = 'RLE Compression'
+      TabOrder = 0
+    end
+    object ifBmp_BitsPerPixel: TComboBox
+      Left = 112
+      Height = 28
+      Top = 8
+      Width = 220
+      ItemHeight = 20
+      Items.Strings = (
+        'Black & White'
+        '16 Colors'
+        '256 Colors/Gray Scale'
+        '15 bit'
+        '16 bit'
+        '24 bit'
+        '32 bit'
+      )
+      ReadOnly = True
+      Style = csDropDownList
+      TabOrder = 1
+    end
+    object Label7: TLabel
+      Left = 16
+      Height = 20
+      Top = 12
+      Width = 88
+      Alignment = taRightJustify
+      Caption = 'Color Depth :'
+    end
+    object ifBmp_GrayScale: TCheckBox
+      Left = 16
+      Height = 24
+      Top = 42
+      Width = 90
+      Caption = 'Gray Scale'
+      TabOrder = 2
+      OnChange = ifBmp_GrayScaleChange
+    end
+  end
 end
 end

+ 109 - 16
bgraformatui.pas

@@ -24,7 +24,7 @@ interface
 uses
 uses
   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, ComCtrls, Buttons,
   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, ComCtrls, Buttons,
   TypInfo, Rtti, FpImage, Laz2_XMLCfg,
   TypInfo, Rtti, FpImage, Laz2_XMLCfg,
-  BCPanel, BCTrackbarUpdown,
+  BCPanel, BCTrackbarUpdown, BCFluentSlider,
   BGRABitmapTypes;
   BGRABitmapTypes;
 
 
 type
 type
@@ -38,17 +38,29 @@ type
   // - the Writer class must have the properties of interest declared as published
   // - the Writer class must have the properties of interest declared as published
   // - the names of the Panel sub controls must be panelname_propertyname
   // - the names of the Panel sub controls must be panelname_propertyname
   //
   //
-  //   for example we have the ifJpeg Writer TBGRAWriterJPEG properties with properties
-  //   published ifJpeg_ProgressiveEncoding; ifJpeg_GrayScale; ifJpeg_CompressionQuality;
+  //   for example we have the ifJpeg Writer TBGRAWriterJPEG
+  //   published
+  //     property ProgressiveEncoding;
+  //     property GrayScale;
+  //     property CompressionQuality;
+  //
   //   the corresponding UI will be
   //   the corresponding UI will be
-  //   ifJpeg : TBCPanel
-  //   ifJpeg_ProgressiveEncoding: TCheckBox;
-  //   ifJpeg_GrayScale: TCheckBox;
-  //   ifJpeg_CompressionQuality: TBCTrackbarUpdown;
+  //     ifJpeg : TBCPanel
+  //       ifJpeg_ProgressiveEncoding: TCheckBox;
+  //       ifJpeg_GrayScale: TCheckBox;
+  //       ifJpeg_CompressionQuality: TBCTrackbarUpdown;
 
 
   { TBGRAFormatUIContainer }
   { TBGRAFormatUIContainer }
 
 
   TBGRAFormatUIContainer = class(TForm)
   TBGRAFormatUIContainer = class(TForm)
+    ifBmp_BitsPerPixel: TComboBox;
+    ifBmp_GrayScale: TCheckBox;
+    ifPng_CompressionLevel: TBCFluentSlider;
+    ifPng: TBCPanel;
+    ifPng_GrayScale: TCheckBox;
+    ifPng_WordSized: TCheckBox;
+    ifBmp: TBCPanel;
+    ifBmp_RLECompress: TCheckBox;
     ifTiff_SaveCMYKAsRGB: TCheckBox;
     ifTiff_SaveCMYKAsRGB: TCheckBox;
     ifTiff_PremultiplyRGB: TCheckBox;
     ifTiff_PremultiplyRGB: TCheckBox;
     ifTiff: TBCPanel;
     ifTiff: TBCPanel;
@@ -58,13 +70,24 @@ type
     ifJpeg_GrayScale: TCheckBox;
     ifJpeg_GrayScale: TCheckBox;
     ifJpeg: TBCPanel;
     ifJpeg: TBCPanel;
     Label1: TLabel;
     Label1: TLabel;
+    Label2: TLabel;
+    Label3: TLabel;
+    Label4: TLabel;
+    Label5: TLabel;
+    Label6: TLabel;
+    Label7: TLabel;
     panelButtons: TPanel;
     panelButtons: TPanel;
     ifJpeg_ProgressiveEncoding: TCheckBox;
     ifJpeg_ProgressiveEncoding: TCheckBox;
+    procedure FormCreate(Sender: TObject);
+    procedure ifBmp_GrayScaleChange(Sender: TObject);
   private
   private
     curFormat: TBGRAImageFormat;
     curFormat: TBGRAImageFormat;
     curWriter: TFPCustomImageWriter;
     curWriter: TFPCustomImageWriter;
     rPanelFormat: TBCPanel;
     rPanelFormat: TBCPanel;
 
 
+    //some var for format specific ui
+    oldBmp_BitsPerPixel: Integer;
+
     function AdjustPanels: Boolean;
     function AdjustPanels: Boolean;
     function SelectPanel: TBCPanel;
     function SelectPanel: TBCPanel;
 
 
@@ -96,6 +119,9 @@ implementation
 
 
 {$R *.lfm}
 {$R *.lfm}
 
 
+const
+  BMP_BitsValidValues: array[0..6] of Integer = (1,4,8,15,16,24,32);
+
 { TBGRAFormatUIContainer }
 { TBGRAFormatUIContainer }
 
 
 class function TBGRAFormatUIContainer.Execute(const AFormat: TBGRAImageFormat;
 class function TBGRAFormatUIContainer.Execute(const AFormat: TBGRAImageFormat;
@@ -120,7 +146,7 @@ begin
      AdjustPanels;
      AdjustPanels;
      GetWriterProperties;
      GetWriterProperties;
 
 
-     if (ShowModal = mrOk) then
+     if (rPanelFormat <> nil) and (ShowModal = mrOk) then
      begin
      begin
        SetWriterProperties(AWriter);
        SetWriterProperties(AWriter);
        Result:= True;
        Result:= True;
@@ -159,6 +185,10 @@ begin
 end;
 end;
 
 
 function TBGRAFormatUIContainer.SetControlValue(const AValue: TValue; const AControl: TControl): Boolean;
 function TBGRAFormatUIContainer.SetControlValue(const AValue: TValue; const AControl: TControl): Boolean;
+var
+   minVal, maxVal, intVal,
+   i: Integer;
+
 begin
 begin
 (*  Case AValue.Kind of
 (*  Case AValue.Kind of
     tkInteger:;
     tkInteger:;
@@ -184,6 +214,15 @@ begin
 *)
 *)
   Result:= False;
   Result:= False;
   try
   try
+     Case AValue.Kind of
+       tkInteger: intVal:= AValue.AsInteger;
+       tkEnumeration: begin
+         minVal:= AValue.TypeData^.MinValue;
+         maxVal:= AValue.TypeData^.MaxValue;
+         intVal:= AValue.AsOrdinal;
+       end;
+     end;
+
      //Types will be added as we use them,
      //Types will be added as we use them,
      //it is the responsibility of the UI creator not to put in crap like
      //it is the responsibility of the UI creator not to put in crap like
      //a checkbox that takes the value from an integer, etc...
      //a checkbox that takes the value from an integer, etc...
@@ -192,10 +231,28 @@ begin
      then TCheckBox(AControl).Checked:= AValue.AsBoolean
      then TCheckBox(AControl).Checked:= AValue.AsBoolean
      else
      else
      if (AControl is TBCTrackbarUpdown)
      if (AControl is TBCTrackbarUpdown)
-     then TBCTrackbarUpdown(AControl).Value:= AValue.AsInteger
+     then TBCTrackbarUpdown(AControl).Value:= intVal
      else
      else
      if (AControl is TTrackbar)
      if (AControl is TTrackbar)
-     then TTrackbar(AControl).Position:= AValue.AsInteger;
+     then TTrackbar(AControl).Position:= intVal
+     else
+     if (AControl is TComboBox)
+     then with TComboBox(AControl) do
+          begin
+            i:= Items.IndexOfObject(TObject(PtrUInt(intVal)));
+            if (i > -1) then ItemIndex:= i;
+          end
+     else
+     if (AControl is TBCFluentSlider)
+     then with TBCFluentSlider(AControl) do
+          begin
+            if (AValue.Kind = tkEnumeration) then
+            begin
+              MinValue:= minVal;
+              MaxValue:= maxVal;
+            end;
+            Value:= intVal;
+          end;
 
 
     Result:= True;
     Result:= True;
   except
   except
@@ -218,7 +275,16 @@ begin
      then AValue:= TBCTrackbarUpdown(AControl).Value
      then AValue:= TBCTrackbarUpdown(AControl).Value
      else
      else
      if (AControl is TTrackbar)
      if (AControl is TTrackbar)
-     then AValue:= TTrackbar(AControl).Position;
+     then AValue:= TTrackbar(AControl).Position
+     else
+     if (AControl is TComboBox)
+     then with TComboBox(AControl) do
+          begin
+            if (ItemIndex > -1) then AValue:= Integer(PtrUInt(Items.Objects[ItemIndex]));
+          end
+     else
+     if (AControl is TBCFluentSlider)
+     then AValue:= TBCFluentSlider(AControl).Value;
 
 
     Result:= True;
     Result:= True;
   except
   except
@@ -338,6 +404,35 @@ begin
   end;
   end;
 end;
 end;
 
 
+procedure TBGRAFormatUIContainer.ifBmp_GrayScaleChange(Sender: TObject);
+begin
+  if ifBmp_GrayScale.Checked
+  then begin
+         oldBmp_BitsPerPixel:= ifBmp_BitsPerPixel.ItemIndex;
+         ifBmp_BitsPerPixel.ItemIndex:= 2; //GrayScale
+       end
+  else begin
+         if (oldBmp_BitsPerPixel > -1) then ifBmp_BitsPerPixel.ItemIndex:= oldBmp_BitsPerPixel;
+       end;
+
+  ifBmp_RLECompress.Enabled:= ifBmp_GrayScale.Checked;
+  ifBmp_BitsPerPixel.Enabled:= not(ifBmp_GrayScale.Checked);
+end;
+
+procedure TBGRAFormatUIContainer.FormCreate(Sender: TObject);
+var
+   i: Integer;
+
+begin
+  //Bitmap Format
+  oldBmp_BitsPerPixel:= -1;
+
+  //TO-DO: Does not works test better tomorrow
+  //Fill Bits x Pixels Objects Values
+  for i:=0 to ifBmp_BitsPerPixel.Items.Count-1 do
+    ifBmp_BitsPerPixel.Items.Objects[i]:= TObject(PtrUInt(BMP_BitsValidValues[i]));
+end;
+
 function TBGRAFormatUIContainer.AdjustPanels: Boolean;
 function TBGRAFormatUIContainer.AdjustPanels: Boolean;
 var
 var
    pName: String;
    pName: String;
@@ -355,7 +450,8 @@ begin
     curControl:= Controls[i];
     curControl:= Controls[i];
 
 
     if (curControl <> nil) and
     if (curControl <> nil) and
-       (curControl is TBCPanel) then
+       (curControl is TBCPanel) and
+       (curControl.Enabled) then
     begin
     begin
       if (CompareText(curControl.Name, pName) = 0) then
       if (CompareText(curControl.Name, pName) = 0) then
       begin
       begin
@@ -370,11 +466,9 @@ begin
   if Result then
   if Result then
   begin
   begin
     rPanelFormat.Top:= 0; rPanelFormat.Left:= 0;
     rPanelFormat.Top:= 0; rPanelFormat.Left:= 0;
-    {$ifopt D-}
     rPanelFormat.BevelInner:= bvNone;
     rPanelFormat.BevelInner:= bvNone;
     rPanelFormat.BevelOuter:= bvNone;
     rPanelFormat.BevelOuter:= bvNone;
     rPanelFormat.Caption:='';
     rPanelFormat.Caption:='';
-    {$endif}
     Self.Width:= rPanelFormat.Width;
     Self.Width:= rPanelFormat.Width;
     Self.Height:= rPanelFormat.Height+panelButtons.Height;
     Self.Height:= rPanelFormat.Height+panelButtons.Height;
 
 
@@ -402,6 +496,7 @@ begin
 
 
       if (curControl <> nil) and
       if (curControl <> nil) and
          (curControl is TBCPanel) and
          (curControl is TBCPanel) and
+         (curControl.Enabled) and
          (CompareText(curControl.Name, pName) = 0) then
          (CompareText(curControl.Name, pName) = 0) then
       begin
       begin
         Result:= TBCPanel(curControl);
         Result:= TBCPanel(curControl);
@@ -412,11 +507,9 @@ begin
   if (Result <> nil) then
   if (Result <> nil) then
   begin
   begin
     Result.Top:= 0; Result.Left:= 0;
     Result.Top:= 0; Result.Left:= 0;
-    {$ifopt D-}
     Result.BevelInner:= bvNone;
     Result.BevelInner:= bvNone;
     Result.BevelOuter:= bvNone;
     Result.BevelOuter:= bvNone;
     Result.Caption:='';
     Result.Caption:='';
-    {$endif}
   end;
   end;
 
 
   rPanelFormat:= Result;
   rPanelFormat:= Result;

BIN
test/test_formatui/test_formatui.ico


+ 134 - 0
test/test_formatui/test_formatui.lpi

@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="12"/>
+    <PathDelim Value="\"/>
+    <General>
+      <SessionStorage Value="InProjectDir"/>
+      <Title Value="test_formatui"/>
+      <Scaled Value="True"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+      <XPManifest>
+        <DpiAware Value="True"/>
+      </XPManifest>
+      <Icon Value="0"/>
+    </General>
+    <BuildModes>
+      <Item Name="Debug" Default="True"/>
+      <Item Name="Release">
+        <CompilerOptions>
+          <Version Value="11"/>
+          <PathDelim Value="\"/>
+          <Target>
+            <Filename Value="bin\$(TargetCPU)-$(TargetOS)\test_formatui"/>
+          </Target>
+          <SearchPaths>
+            <IncludeFiles Value="$(ProjOutDir)"/>
+            <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
+          </SearchPaths>
+          <CodeGeneration>
+            <SmartLinkUnit Value="True"/>
+            <Optimizations>
+              <OptimizationLevel Value="3"/>
+            </Optimizations>
+          </CodeGeneration>
+          <Linking>
+            <Debugging>
+              <GenerateDebugInfo Value="False"/>
+              <RunWithoutDebug Value="True"/>
+              <StripSymbols Value="True"/>
+            </Debugging>
+            <LinkSmart Value="True"/>
+            <Options>
+              <Win32>
+                <GraphicApplication Value="True"/>
+              </Win32>
+            </Options>
+          </Linking>
+        </CompilerOptions>
+      </Item>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <UseFileFilters Value="True"/>
+    </PublishOptions>
+    <RunParams>
+      <FormatVersion Value="2"/>
+    </RunParams>
+    <RequiredPackages>
+      <Item>
+        <PackageName Value="bgracontrols"/>
+      </Item>
+      <Item>
+        <PackageName Value="BGRABitmapPack"/>
+      </Item>
+      <Item>
+        <PackageName Value="LCL"/>
+      </Item>
+    </RequiredPackages>
+    <Units>
+      <Unit>
+        <Filename Value="test_formatui.lpr"/>
+        <IsPartOfProject Value="True"/>
+      </Unit>
+      <Unit>
+        <Filename Value="test_formatui_main.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="SaveFile_Settings"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
+      </Unit>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="11"/>
+    <PathDelim Value="\"/>
+    <Target>
+      <Filename Value="bin\$(TargetCPU)-$(TargetOS)\test_formatui"/>
+    </Target>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+      <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
+    </SearchPaths>
+    <Parsing>
+      <SyntaxOptions>
+        <IncludeAssertionCode Value="True"/>
+      </SyntaxOptions>
+    </Parsing>
+    <CodeGeneration>
+      <Checks>
+        <IOChecks Value="True"/>
+        <RangeChecks Value="True"/>
+        <OverflowChecks Value="True"/>
+        <StackChecks Value="True"/>
+      </Checks>
+      <VerifyObjMethodCallValidity Value="True"/>
+    </CodeGeneration>
+    <Linking>
+      <Debugging>
+        <DebugInfoType Value="dsDwarf3"/>
+        <UseHeaptrc Value="True"/>
+        <TrashVariables Value="True"/>
+      </Debugging>
+      <Options>
+        <Win32>
+          <GraphicApplication Value="True"/>
+        </Win32>
+      </Options>
+    </Linking>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions>
+      <Item>
+        <Name Value="EAbort"/>
+      </Item>
+      <Item>
+        <Name Value="ECodetoolError"/>
+      </Item>
+      <Item>
+        <Name Value="EFOpenError"/>
+      </Item>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 27 - 0
test/test_formatui/test_formatui.lpr

@@ -0,0 +1,27 @@
+program test_formatui;
+
+{$mode objfpc}{$H+}
+
+uses
+  {$IFDEF UNIX}
+  cthreads,
+  {$ENDIF}
+  {$IFDEF HASAMIGA}
+  athreads,
+  {$ENDIF}
+  Interfaces, // this includes the LCL widgetset
+  Forms, test_formatui_main;
+
+{$R *.res}
+
+begin
+  RequireDerivedFormResource:=True;
+  Application.Scaled:=True;
+  {$PUSH}{$WARN 5044 OFF}
+  Application.MainFormOnTaskbar:=True;
+  {$POP}
+  Application.Initialize;
+  Application.CreateForm(TSaveFile_Settings, SaveFile_Settings);
+  Application.Run;
+end.
+

+ 358 - 0
test/test_formatui/test_formatui_main.lfm

@@ -0,0 +1,358 @@
+object SaveFile_Settings: TSaveFile_Settings
+  Left = 416
+  Height = 450
+  Top = 239
+  Width = 780
+  BorderIcons = [biSystemMenu]
+  BorderStyle = bsSingle
+  Caption = 'Save as Files Settings'
+  ClientHeight = 450
+  ClientWidth = 780
+  DesignTimePPI = 120
+  Position = poScreenCenter
+  OnClose = FormClose
+  OnShow = FormShow
+  object panelWrite: TBCPanel
+    Left = 374
+    Height = 450
+    Top = 0
+    Width = 406
+    Align = alRight
+    Background.Color = clBtnFace
+    Background.Gradient1.StartColor = clWhite
+    Background.Gradient1.EndColor = clBlack
+    Background.Gradient1.GradientType = gtLinear
+    Background.Gradient1.Point1XPercent = 0
+    Background.Gradient1.Point1YPercent = 0
+    Background.Gradient1.Point2XPercent = 0
+    Background.Gradient1.Point2YPercent = 100
+    Background.Gradient2.StartColor = clWhite
+    Background.Gradient2.EndColor = clBlack
+    Background.Gradient2.GradientType = gtLinear
+    Background.Gradient2.Point1XPercent = 0
+    Background.Gradient2.Point1YPercent = 0
+    Background.Gradient2.Point2XPercent = 0
+    Background.Gradient2.Point2YPercent = 100
+    Background.Gradient1EndPercent = 35
+    Background.Style = bbsColor
+    BevelInner = bvLowered
+    BevelOuter = bvRaised
+    BevelWidth = 1
+    Border.Style = bboNone
+    FontEx.Color = clDefault
+    FontEx.FontQuality = fqSystemClearType
+    FontEx.Shadow = False
+    FontEx.ShadowRadius = 5
+    FontEx.ShadowOffsetX = 5
+    FontEx.ShadowOffsetY = 5
+    FontEx.Style = []
+    ParentBackground = False
+    Rounding.RoundX = 1
+    Rounding.RoundY = 1
+    TabOrder = 0
+    object Label6: TLabel
+      Left = 45
+      Height = 20
+      Top = 48
+      Width = 49
+      Alignment = taRightJustify
+      Caption = 'Folder :'
+    end
+    object dirDestination: TDirectoryEdit
+      Left = 100
+      Height = 28
+      Top = 48
+      Width = 300
+      ShowHidden = False
+      ButtonWidth = 29
+      NumGlyphs = 1
+      MaxLength = 0
+      TabOrder = 0
+      OnChange = dirDestinationChange
+    end
+    object cbSaveFormat: TComboBox
+      Left = 100
+      Height = 28
+      Top = 112
+      Width = 300
+      ItemHeight = 20
+      Style = csDropDownList
+      TabOrder = 1
+      OnChange = cbSaveFormatChange
+    end
+    object btSave: TBCButton
+      Left = 4
+      Height = 41
+      Top = 1
+      Width = 154
+      StateClicked.Background.Gradient1.StartColor = 8404992
+      StateClicked.Background.Gradient1.EndColor = 4194304
+      StateClicked.Background.Gradient1.GradientType = gtRadial
+      StateClicked.Background.Gradient1.Point1XPercent = 50
+      StateClicked.Background.Gradient1.Point1YPercent = 100
+      StateClicked.Background.Gradient1.Point2XPercent = 0
+      StateClicked.Background.Gradient1.Point2YPercent = 0
+      StateClicked.Background.Gradient2.StartColor = clWhite
+      StateClicked.Background.Gradient2.EndColor = clBlack
+      StateClicked.Background.Gradient2.GradientType = gtLinear
+      StateClicked.Background.Gradient2.Point1XPercent = 0
+      StateClicked.Background.Gradient2.Point1YPercent = 0
+      StateClicked.Background.Gradient2.Point2XPercent = 0
+      StateClicked.Background.Gradient2.Point2YPercent = 100
+      StateClicked.Background.Gradient1EndPercent = 100
+      StateClicked.Background.Style = bbsGradient
+      StateClicked.Border.Style = bboNone
+      StateClicked.FontEx.Color = 16770790
+      StateClicked.FontEx.FontQuality = fqSystemClearType
+      StateClicked.FontEx.Shadow = True
+      StateClicked.FontEx.ShadowRadius = 2
+      StateClicked.FontEx.ShadowOffsetX = 1
+      StateClicked.FontEx.ShadowOffsetY = 1
+      StateClicked.FontEx.Style = [fsBold]
+      StateHover.Background.Gradient1.StartColor = 16744448
+      StateHover.Background.Gradient1.EndColor = 8404992
+      StateHover.Background.Gradient1.GradientType = gtRadial
+      StateHover.Background.Gradient1.Point1XPercent = 50
+      StateHover.Background.Gradient1.Point1YPercent = 100
+      StateHover.Background.Gradient1.Point2XPercent = 0
+      StateHover.Background.Gradient1.Point2YPercent = 0
+      StateHover.Background.Gradient2.StartColor = clWhite
+      StateHover.Background.Gradient2.EndColor = clBlack
+      StateHover.Background.Gradient2.GradientType = gtLinear
+      StateHover.Background.Gradient2.Point1XPercent = 0
+      StateHover.Background.Gradient2.Point1YPercent = 0
+      StateHover.Background.Gradient2.Point2XPercent = 0
+      StateHover.Background.Gradient2.Point2YPercent = 100
+      StateHover.Background.Gradient1EndPercent = 100
+      StateHover.Background.Style = bbsGradient
+      StateHover.Border.Style = bboNone
+      StateHover.FontEx.Color = clWhite
+      StateHover.FontEx.FontQuality = fqSystemClearType
+      StateHover.FontEx.Shadow = True
+      StateHover.FontEx.ShadowRadius = 2
+      StateHover.FontEx.ShadowOffsetX = 1
+      StateHover.FontEx.ShadowOffsetY = 1
+      StateHover.FontEx.Style = [fsBold]
+      StateNormal.Background.Gradient1.StartColor = 4194304
+      StateNormal.Background.Gradient1.EndColor = 8405056
+      StateNormal.Background.Gradient1.GradientType = gtLinear
+      StateNormal.Background.Gradient1.Point1XPercent = 0
+      StateNormal.Background.Gradient1.Point1YPercent = 0
+      StateNormal.Background.Gradient1.Point2XPercent = 0
+      StateNormal.Background.Gradient1.Point2YPercent = 100
+      StateNormal.Background.Gradient2.StartColor = 8405056
+      StateNormal.Background.Gradient2.EndColor = 4194304
+      StateNormal.Background.Gradient2.GradientType = gtRadial
+      StateNormal.Background.Gradient2.Point1XPercent = 50
+      StateNormal.Background.Gradient2.Point1YPercent = 100
+      StateNormal.Background.Gradient2.Point2XPercent = 0
+      StateNormal.Background.Gradient2.Point2YPercent = 0
+      StateNormal.Background.Gradient1EndPercent = 60
+      StateNormal.Background.Style = bbsGradient
+      StateNormal.Border.Style = bboNone
+      StateNormal.FontEx.Color = 16770790
+      StateNormal.FontEx.FontQuality = fqSystemClearType
+      StateNormal.FontEx.Shadow = True
+      StateNormal.FontEx.ShadowRadius = 2
+      StateNormal.FontEx.ShadowOffsetX = 1
+      StateNormal.FontEx.ShadowOffsetY = 1
+      StateNormal.FontEx.Style = [fsBold]
+      Caption = 'Save Image'
+      Color = clNone
+      DropDownWidth = 16
+      DropDownArrowSize = 8
+      GlobalOpacity = 255
+      OnClick = btSaveClick
+      ParentColor = False
+      Rounding.RoundX = 12
+      Rounding.RoundY = 12
+      RoundingDropDown.RoundX = 1
+      RoundingDropDown.RoundY = 1
+      TextApplyGlobalOpacity = False
+      MemoryUsage = bmuHigh
+    end
+    object BCLabel9: TLabel
+      Left = 40
+      Height = 20
+      Top = 114
+      Width = 54
+      Alignment = taRightJustify
+      Caption = 'Format :'
+    end
+    object BCLabel10: TLabel
+      Left = 27
+      Height = 20
+      Top = 80
+      Width = 67
+      Alignment = taRightJustify
+      Caption = 'Filename :'
+    end
+    object edFileName: TEdit
+      Left = 100
+      Height = 28
+      Top = 79
+      Width = 250
+      TabOrder = 2
+      Text = 'test_format'
+    end
+    object lbExt: TLabel
+      Left = 354
+      Height = 20
+      Top = 87
+      Width = 25
+      Caption = '.jpg'
+    end
+  end
+  object panelRead: TBCPanel
+    Left = 0
+    Height = 450
+    Top = 0
+    Width = 375
+    Align = alLeft
+    Background.Color = clBtnFace
+    Background.Gradient1.StartColor = clWhite
+    Background.Gradient1.EndColor = clBlack
+    Background.Gradient1.GradientType = gtLinear
+    Background.Gradient1.Point1XPercent = 0
+    Background.Gradient1.Point1YPercent = 0
+    Background.Gradient1.Point2XPercent = 0
+    Background.Gradient1.Point2YPercent = 100
+    Background.Gradient2.StartColor = clWhite
+    Background.Gradient2.EndColor = clBlack
+    Background.Gradient2.GradientType = gtLinear
+    Background.Gradient2.Point1XPercent = 0
+    Background.Gradient2.Point1YPercent = 0
+    Background.Gradient2.Point2XPercent = 0
+    Background.Gradient2.Point2YPercent = 100
+    Background.Gradient1EndPercent = 35
+    Background.Style = bbsColor
+    BevelInner = bvNone
+    BevelOuter = bvRaised
+    BevelWidth = 1
+    Border.Style = bboNone
+    FontEx.Color = clDefault
+    FontEx.FontQuality = fqSystemClearType
+    FontEx.Shadow = False
+    FontEx.ShadowRadius = 5
+    FontEx.ShadowOffsetX = 5
+    FontEx.ShadowOffsetY = 5
+    FontEx.Style = []
+    ParentBackground = False
+    Rounding.RoundX = 1
+    Rounding.RoundY = 1
+    TabOrder = 1
+    object bcImage: TBCRoundedImage
+      Left = 2
+      Height = 370
+      Top = 48
+      Width = 370
+      Style = isSquare
+      BorderStyle = []
+      Rounding = 10
+      Quality = rfBestQuality
+      Proportional = True
+    end
+    object btLoad: TBCButton
+      Left = 4
+      Height = 41
+      Top = 1
+      Width = 154
+      StateClicked.Background.Gradient1.StartColor = 8404992
+      StateClicked.Background.Gradient1.EndColor = 4194304
+      StateClicked.Background.Gradient1.GradientType = gtRadial
+      StateClicked.Background.Gradient1.Point1XPercent = 50
+      StateClicked.Background.Gradient1.Point1YPercent = 100
+      StateClicked.Background.Gradient1.Point2XPercent = 0
+      StateClicked.Background.Gradient1.Point2YPercent = 0
+      StateClicked.Background.Gradient2.StartColor = clWhite
+      StateClicked.Background.Gradient2.EndColor = clBlack
+      StateClicked.Background.Gradient2.GradientType = gtLinear
+      StateClicked.Background.Gradient2.Point1XPercent = 0
+      StateClicked.Background.Gradient2.Point1YPercent = 0
+      StateClicked.Background.Gradient2.Point2XPercent = 0
+      StateClicked.Background.Gradient2.Point2YPercent = 100
+      StateClicked.Background.Gradient1EndPercent = 100
+      StateClicked.Background.Style = bbsGradient
+      StateClicked.Border.Style = bboNone
+      StateClicked.FontEx.Color = 16770790
+      StateClicked.FontEx.FontQuality = fqSystemClearType
+      StateClicked.FontEx.Shadow = True
+      StateClicked.FontEx.ShadowRadius = 2
+      StateClicked.FontEx.ShadowOffsetX = 1
+      StateClicked.FontEx.ShadowOffsetY = 1
+      StateClicked.FontEx.Style = [fsBold]
+      StateHover.Background.Gradient1.StartColor = 16744448
+      StateHover.Background.Gradient1.EndColor = 8404992
+      StateHover.Background.Gradient1.GradientType = gtRadial
+      StateHover.Background.Gradient1.Point1XPercent = 50
+      StateHover.Background.Gradient1.Point1YPercent = 100
+      StateHover.Background.Gradient1.Point2XPercent = 0
+      StateHover.Background.Gradient1.Point2YPercent = 0
+      StateHover.Background.Gradient2.StartColor = clWhite
+      StateHover.Background.Gradient2.EndColor = clBlack
+      StateHover.Background.Gradient2.GradientType = gtLinear
+      StateHover.Background.Gradient2.Point1XPercent = 0
+      StateHover.Background.Gradient2.Point1YPercent = 0
+      StateHover.Background.Gradient2.Point2XPercent = 0
+      StateHover.Background.Gradient2.Point2YPercent = 100
+      StateHover.Background.Gradient1EndPercent = 100
+      StateHover.Background.Style = bbsGradient
+      StateHover.Border.Style = bboNone
+      StateHover.FontEx.Color = clWhite
+      StateHover.FontEx.FontQuality = fqSystemClearType
+      StateHover.FontEx.Shadow = True
+      StateHover.FontEx.ShadowRadius = 2
+      StateHover.FontEx.ShadowOffsetX = 1
+      StateHover.FontEx.ShadowOffsetY = 1
+      StateHover.FontEx.Style = [fsBold]
+      StateNormal.Background.Gradient1.StartColor = 4194304
+      StateNormal.Background.Gradient1.EndColor = 8405056
+      StateNormal.Background.Gradient1.GradientType = gtLinear
+      StateNormal.Background.Gradient1.Point1XPercent = 0
+      StateNormal.Background.Gradient1.Point1YPercent = 0
+      StateNormal.Background.Gradient1.Point2XPercent = 0
+      StateNormal.Background.Gradient1.Point2YPercent = 100
+      StateNormal.Background.Gradient2.StartColor = 8405056
+      StateNormal.Background.Gradient2.EndColor = 4194304
+      StateNormal.Background.Gradient2.GradientType = gtRadial
+      StateNormal.Background.Gradient2.Point1XPercent = 50
+      StateNormal.Background.Gradient2.Point1YPercent = 100
+      StateNormal.Background.Gradient2.Point2XPercent = 0
+      StateNormal.Background.Gradient2.Point2YPercent = 0
+      StateNormal.Background.Gradient1EndPercent = 60
+      StateNormal.Background.Style = bbsGradient
+      StateNormal.Border.Style = bboNone
+      StateNormal.FontEx.Color = 16770790
+      StateNormal.FontEx.FontQuality = fqSystemClearType
+      StateNormal.FontEx.Shadow = True
+      StateNormal.FontEx.ShadowRadius = 2
+      StateNormal.FontEx.ShadowOffsetX = 1
+      StateNormal.FontEx.ShadowOffsetY = 1
+      StateNormal.FontEx.Style = [fsBold]
+      Caption = 'Load Image'
+      Color = clNone
+      DropDownWidth = 16
+      DropDownArrowSize = 8
+      GlobalOpacity = 255
+      OnClick = btLoadClick
+      ParentColor = False
+      Rounding.RoundX = 12
+      Rounding.RoundY = 12
+      RoundingDropDown.RoundX = 1
+      RoundingDropDown.RoundY = 1
+      TextApplyGlobalOpacity = False
+      MemoryUsage = bmuHigh
+    end
+    object lbDetails: TLabel
+      Left = 2
+      Height = 20
+      Top = 426
+      Width = 45
+      Caption = 'image:'
+    end
+  end
+  object openPictBGRA: TBGRAOpenPictureDialog
+    Left = 124
+    Top = 104
+  end
+end

+ 183 - 0
test/test_formatui/test_formatui_main.pas

@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: LGPL-3.0-linking-exception
+{
+  Created by BGRA Controls Team
+
+         (c) 2025 Massimo Magnano
+
+  Test Save File Format Settings Form
+}
+
+unit test_formatui_main;
+
+{$mode ObjFPC}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, EditBtn, Buttons,
+  FpImage,
+  BGRABitmapTypes,
+  BCPanel, BCLabel, BCRoundedImage, BCButton, BGRADialogs;
+
+type
+  { TSaveFile_Settings }
+
+  TSaveFile_Settings = class(TForm)
+    BCLabel10: TLabel;
+    BCLabel9: TLabel;
+    btLoad: TBCButton;
+    btSave: TBCButton;
+    edFileName: TEdit;
+    lbExt: TLabel;
+    lbDetails: TLabel;
+    openPictBGRA: TBGRAOpenPictureDialog;
+    panelRead: TBCPanel;
+    bcImage: TBCRoundedImage;
+    panelWrite: TBCPanel;
+    cbSaveFormat: TComboBox;
+    dirDestination: TDirectoryEdit;
+    Label6: TLabel;
+    procedure btLoadClick(Sender: TObject);
+    procedure btSaveClick(Sender: TObject);
+    procedure cbSaveFormatChange(Sender: TObject);
+    procedure dirDestinationChange(Sender: TObject);
+    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
+    procedure FormShow(Sender: TObject);
+
+  private
+    SaveFormat,
+    UserSaveFormat: TBGRAImageFormat;
+    SaveWriter,
+    UserSaveWriter: TFPCustomImageWriter;
+    SavePath: String;
+    panelFormatUI: TBCPanel;
+    createdWriter: Boolean;
+
+    procedure BuildSaveFormats;
+    procedure AdjustFormatPanel;
+
+  public
+
+  end;
+
+var
+  SaveFile_Settings: TSaveFile_Settings;
+
+implementation
+
+{$R *.lfm}
+
+uses Math, BGRAFormatUI;
+
+{ TSaveFile_Settings }
+
+procedure TSaveFile_Settings.BuildSaveFormats;
+var
+  iFormat: TBGRAImageFormat;
+
+begin
+  cbSaveFormat.Clear;
+
+  for iFormat:=Low(TBGRAImageFormat) to High(TBGRAImageFormat) do
+  begin
+    if (iFormat <> ifUnknown) and (DefaultBGRAImageWriter[iFormat] <> nil) then
+    begin
+      cbSaveFormat.Items.AddObject(BGRAImageFormat[iFormat].TypeName+' ('+SuggestImageExtension(iFormat)+')',
+                                   TObject(PTRUInt(iFormat)));
+    end;
+  end;
+
+  if (cbSaveFormat.Items.Count > 0) then cbSaveFormat.ItemIndex:= 0;
+end;
+
+procedure TSaveFile_Settings.AdjustFormatPanel;
+begin
+  lbExt.Caption:= '.'+SuggestImageExtension(SaveFormat);
+
+  if (panelFormatUI <> nil)
+  then begin
+         panelFormatUI.Top:= 150; panelFormatUI.Left:= 10;
+         Width:= Max(780, panelFormatUI.Width+130);
+         Height:= Max(450, panelFormatUI.Height+150);
+
+         panelFormatUI.Parent:= panelWrite;
+         panelFormatUI.Visible:= True;
+       end
+  else begin
+         Width:= 780;
+         Height:= 450;
+       end;
+end;
+
+procedure TSaveFile_Settings.cbSaveFormatChange(Sender: TObject);
+begin
+  SaveFormat:= TBGRAImageFormat(PTRUInt(cbSaveFormat.Items.Objects[cbSaveFormat.ItemIndex]));
+  SaveWriter.Free;
+  SaveWriter:= CreateBGRAImageWriter(SaveFormat, True);
+
+  if (panelFormatUI <> nil) then panelFormatUI.Visible:= False;
+
+  TBGRAFormatUIContainer.GetUI(SaveFormat, SaveWriter, panelFormatUI);
+  AdjustFormatPanel;
+end;
+
+procedure TSaveFile_Settings.btLoadClick(Sender: TObject);
+begin
+  try
+     if openPictBGRA.Execute then
+     begin
+       bcImage.Bitmap.LoadFromFile(openPictBGRA.FileName); //'c:\tmp\Acquisitions Book 1.03.01, Byzantine.jpg'
+       bcImage.Invalidate;
+       lbDetails.Caption:= 'image: '+IntToStr(bcImage.Bitmap.Width)+' x '+IntToStr(bcImage.Bitmap.Height);
+     end;
+
+  finally
+  end;
+end;
+
+procedure TSaveFile_Settings.btSaveClick(Sender: TObject);
+begin
+  if not(bcImage.Bitmap.Empty) then
+  begin
+    if (BGRAFormatUIContainer <> nil) and
+       (panelFormatUI <> nil)
+    then BGRAFormatUIContainer.SetWriterProperties(SaveWriter);
+
+    bcImage.Bitmap.SaveToFile(SavePath+DirectorySeparator+edFileName.Text+'.'+SuggestImageExtension(SaveFormat),
+                              SaveWriter);
+  end;
+end;
+
+procedure TSaveFile_Settings.dirDestinationChange(Sender: TObject);
+begin
+  SavePath :=dirDestination.Directory;
+end;
+
+procedure TSaveFile_Settings.FormClose(Sender: TObject; var CloseAction: TCloseAction);
+begin
+  if (SaveWriter<>nil) then SaveWriter.Free;
+  if (BGRAFormatUIContainer <> nil) then BGRAFormatUIContainer.Free;
+end;
+
+procedure TSaveFile_Settings.FormShow(Sender: TObject);
+begin
+  try
+     panelFormatUI:= nil;
+     BuildSaveFormats;
+
+     dirDestination.Directory:= ExtractFileDir(ParamStr(0));
+
+     //Select Current Format, if not found Select Jpeg
+     cbSaveFormat.ItemIndex:= cbSaveFormat.Items.IndexOfObject(TObject(PTRUInt(ifJpeg)));
+     SaveFormat:= ifJpeg;
+     SaveWriter:= CreateBGRAImageWriter(SaveFormat, True);
+
+     TBGRAFormatUIContainer.GetUI(SaveFormat, SaveWriter, panelFormatUI);
+
+  finally
+    AdjustFormatPanel;
+  end;
+end;
+
+end.
+