瀏覽代碼

Merge pull request #206 from bgrabitmap/dev-lazpaint

Dev lazpaint 7.1.5
circular17 4 年之前
父節點
當前提交
7f9e65b424

+ 6 - 1
lazpaint.logic

@@ -4,7 +4,12 @@ package lazpaintembeddedpack.lpk
 const lazpainttype.pas LazPaintVersion
 text release/windows/lazpaint.iss "#define MyAppVersion ""$(Version)"""
 text release/debian/debian/control "Version: $(Version)"
-echo "DON'T FORGET TO UPDATE release/debian/changelog"
 text release/macOS/makedmg.sh "appversion=$(Version)"
 bundle release/macOS/LazPaint.app
 copy ../resources/icon/lazpaint.icns release/macOS/LazPaint.app/Contents/Resources/lazpaint.icns
+if exists ../../lazpaint.github.io/app.js
+  text ../../lazpaint.github.io/app.js "    var version = '$(Version)'"
+else
+  echo "WEBSITE FOLDER NOT FOUND, UPDATE MANUALLY app.js"
+end
+echo ">> DON'T FORGET TO ADD VERSION IN release/debian/changelog <<"

+ 76 - 94
lazpaint/dialog/ubrowseimages.lfm

@@ -1,12 +1,11 @@
 object FBrowseImages: TFBrowseImages
   Left = 376
-  Height = 375
+  Height = 300
   Top = 101
-  Width = 855
+  Width = 684
   Caption = 'Browse images'
-  ClientHeight = 375
-  ClientWidth = 855
-  DesignTimePPI = 120
+  ClientHeight = 300
+  ClientWidth = 684
   KeyPreview = True
   OnCloseQuery = FormCloseQuery
   OnCreate = FormCreate
@@ -18,119 +17,118 @@ object FBrowseImages: TFBrowseImages
   OnUTF8KeyPress = FormUTF8KeyPress
   Position = poScreenCenter
   ShowInTaskBar = stAlways
-  LCLVersion = '2.0.2.0'
+  LCLVersion = '2.0.10.0'
   object Panel1: TPanel
-    Left = 580
-    Height = 375
+    Left = 464
+    Height = 300
     Top = 0
-    Width = 275
+    Width = 220
     Align = alClient
-    ClientHeight = 375
-    ClientWidth = 275
+    ClientHeight = 300
+    ClientWidth = 220
     ParentFont = False
-    TabOrder = 0
+    TabOrder = 1
     object Label_Status: TLabel
-      Left = 4
-      Height = 22
-      Top = 6
-      Width = 4
+      Left = 3
+      Height = 15
+      Top = 5
+      Width = 3
       Caption = '.'
       ParentColor = False
       ParentFont = False
     end
     object vsPreview: TBGRAVirtualScreen
-      Left = 4
-      Height = 338
-      Top = 32
-      Width = 267
+      Left = 3
+      Height = 270
+      Top = 26
+      Width = 214
       Alignment = taLeftJustify
       Anchors = [akTop, akLeft, akRight, akBottom]
       Color = clGray
       ParentColor = False
       ParentFont = False
-      TabOrder = 0
+      TabOrder = 2
     end
     object ListBox_RecentDirs: TListBox
-      Left = 4
-      Height = 337
-      Top = 32
-      Width = 265
+      Left = 3
+      Height = 269
+      Top = 26
+      Width = 212
       Anchors = [akTop, akLeft, akRight, akBottom]
       ItemHeight = 0
       OnClick = ListBox_RecentDirsClick
       ParentFont = False
       ScrollWidth = 263
       TabOrder = 1
-      TopIndex = -1
     end
     object CheckBox_UseDirectoryOnStartup: TCheckBox
-      Left = 70
-      Height = 26
-      Top = 4
-      Width = 222
+      Left = 56
+      Height = 19
+      Top = 3
+      Width = 168
       Caption = 'Use this directory on startup'
       ParentFont = False
-      TabOrder = 2
+      TabOrder = 0
       Visible = False
     end
   end
   object Splitter1: TSplitter
-    Left = 572
-    Height = 375
+    Left = 458
+    Height = 300
     Top = 0
-    Width = 8
+    Width = 6
     MinSize = 64
   end
   object Panel2: TPanel
     Left = 0
-    Height = 375
+    Height = 300
     Top = 0
-    Width = 572
+    Width = 458
     Align = alLeft
-    ClientHeight = 375
-    ClientWidth = 572
+    ClientHeight = 300
+    ClientWidth = 458
     ParentFont = False
     TabOrder = 2
     object Panel3: TPanel
       Left = 1
-      Height = 91
+      Height = 73
       Top = 1
-      Width = 570
+      Width = 456
       Align = alTop
-      ClientHeight = 91
-      ClientWidth = 570
+      ClientHeight = 73
+      ClientWidth = 456
       ParentFont = False
       TabOrder = 0
       object ToolBar1: TToolBar
         Left = 1
-        Height = 41
+        Height = 33
         Top = 2
-        Width = 281
+        Width = 198
         Align = alNone
-        ButtonHeight = 40
-        ButtonWidth = 40
+        ButtonHeight = 32
+        ButtonWidth = 32
         EdgeBorders = []
         Images = ImageListToolbar
         ParentFont = False
         ParentShowHint = False
         ShowHint = True
-        TabOrder = 0
+        TabOrder = 3
         object ToolButton_GoUp: TToolButton
-          Left = 161
+          Left = 145
           Hint = 'Go one directory up'
           Top = 0
           ImageIndex = 0
           OnClick = ToolButton_GoUpClick
         end
         object ToolButton_ViewBigIcon: TToolButton
-          Left = 81
+          Left = 73
           Hint = 'Show big icons'
           Top = 0
           ImageIndex = 2
           OnClick = ToolButton_ViewBigIconClick
         end
         object ToolButton_ViewDetails: TToolButton
-          Left = 41
+          Left = 37
           Hint = 'Show details and preview'
           Top = 0
           ImageIndex = 3
@@ -145,7 +143,7 @@ object FBrowseImages: TFBrowseImages
           OnClick = ToolButton_OpenSelectedFilesClick
         end
         object Tool_SelectDrive: TToolButton
-          Left = 121
+          Left = 109
           Hint = 'Select drive'
           Top = 0
           ImageIndex = 6
@@ -153,41 +151,42 @@ object FBrowseImages: TFBrowseImages
           Visible = False
         end
         object ToolButton_CreateFolderOrContainer: TToolButton
-          Left = 201
+          Left = 1
           Hint = 'Create folder or container'
-          Top = 0
+          Top = 32
           ImageIndex = 8
           OnClick = ToolButton_CreateFolderOrContainerClick
         end
       end
       object Edit_Filename: TEdit
-        Left = 280
-        Height = 34
-        Top = 50
-        Width = 280
+        Left = 224
+        Height = 23
+        Top = 40
+        Width = 224
         Anchors = [akTop, akLeft, akRight]
         OnChange = Edit_FilenameChange
         ParentFont = False
-        TabOrder = 1
+        TabOrder = 2
       end
       object DirectoryEdit1: TEdit
-        Left = 280
-        Height = 34
-        Top = 6
-        Width = 280
+        Left = 200
+        Height = 23
+        Top = 5
+        Width = 248
         Anchors = [akTop, akLeft, akRight]
         OnChange = DirectoryEdit1Change
         ParentFont = False
-        TabOrder = 2
+        TabOrder = 0
       end
       object ComboBox_FileExtension: TBCComboBox
-        Left = 8
-        Height = 34
-        Top = 50
-        Width = 262
+        Left = 6
+        Height = 27
+        Top = 40
+        Width = 210
         ItemIndex = -1
         ArrowSize = 8
         ArrowWidth = 16
+        FocusBorderOpacity = 0
         GlobalOpacity = 255
         MemoryUsage = bmuHigh
         Rounding.RoundX = 3
@@ -195,16 +194,10 @@ object FBrowseImages: TFBrowseImages
         StateClicked.Background.Gradient1.StartColor = clBtnShadow
         StateClicked.Background.Gradient1.EndColor = clBtnFace
         StateClicked.Background.Gradient1.GradientType = gtLinear
-        StateClicked.Background.Gradient1.Point1XPercent = 0
-        StateClicked.Background.Gradient1.Point1YPercent = 0
-        StateClicked.Background.Gradient1.Point2XPercent = 0
         StateClicked.Background.Gradient1.Point2YPercent = 250
         StateClicked.Background.Gradient2.StartColor = clBtnShadow
         StateClicked.Background.Gradient2.EndColor = clBtnText
         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 = 70
         StateClicked.Background.Style = bbsGradient
@@ -224,16 +217,10 @@ object FBrowseImages: TFBrowseImages
         StateHover.Background.Gradient1.StartColor = clBtnFace
         StateHover.Background.Gradient1.EndColor = clBtnHighlight
         StateHover.Background.Gradient1.GradientType = gtLinear
-        StateHover.Background.Gradient1.Point1XPercent = 0
-        StateHover.Background.Gradient1.Point1YPercent = 0
-        StateHover.Background.Gradient1.Point2XPercent = 0
         StateHover.Background.Gradient1.Point2YPercent = 150
         StateHover.Background.Gradient2.StartColor = clBtnFace
         StateHover.Background.Gradient2.EndColor = clBtnShadow
         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 = 85
         StateHover.Background.Style = bbsGradient
@@ -253,16 +240,10 @@ object FBrowseImages: TFBrowseImages
         StateNormal.Background.Gradient1.StartColor = clBtnFace
         StateNormal.Background.Gradient1.EndColor = clBtnHighlight
         StateNormal.Background.Gradient1.GradientType = gtLinear
-        StateNormal.Background.Gradient1.Point1XPercent = 0
-        StateNormal.Background.Gradient1.Point1YPercent = 0
-        StateNormal.Background.Gradient1.Point2XPercent = 0
         StateNormal.Background.Gradient1.Point2YPercent = 150
         StateNormal.Background.Gradient2.StartColor = clBtnFace
         StateNormal.Background.Gradient2.EndColor = clBtnShadow
         StateNormal.Background.Gradient2.GradientType = gtLinear
-        StateNormal.Background.Gradient2.Point1XPercent = 0
-        StateNormal.Background.Gradient2.Point1YPercent = 0
-        StateNormal.Background.Gradient2.Point2XPercent = 0
         StateNormal.Background.Gradient2.Point2YPercent = 100
         StateNormal.Background.Gradient1EndPercent = 70
         StateNormal.Background.Style = bbsGradient
@@ -281,13 +262,14 @@ object FBrowseImages: TFBrowseImages
         StateNormal.FontEx.PaddingLeft = 3
         StaticButton = False
         OnChange = ComboBox_FileExtensionChange
+        TabOrder = 1
       end
     end
     object vsList: TBGRAVirtualScreen
       Left = 1
-      Height = 282
-      Top = 92
-      Width = 570
+      Height = 225
+      Top = 74
+      Width = 456
       Align = alClient
       Alignment = taLeftJustify
       Color = clWindow
@@ -300,8 +282,8 @@ object FBrowseImages: TFBrowseImages
   object ImageList128: TImageList
     Height = 128
     Width = 128
-    left = 50
-    top = 220
+    Left = 40
+    Top = 176
     Bitmap = {
       4C69080000008000000080000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
       FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
@@ -16694,14 +16676,14 @@ object FBrowseImages: TFBrowseImages
     Enabled = False
     Interval = 30
     OnTimer = Timer1Timer
-    left = 320
-    top = 220
+    Left = 256
+    Top = 176
   end
   object ImageListToolbar: TImageList
     Height = 32
     Width = 32
-    left = 234
-    top = 221
+    Left = 187
+    Top = 177
     Bitmap = {
       4C69090000002000000020000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000

+ 24 - 15
lazpaint/dialog/ubrowseimages.pas

@@ -15,7 +15,7 @@ type
 
   { TFBrowseImages }
 
-  TFBrowseImages = class(TForm)
+   TFBrowseImages = class(TForm)
     ComboBox_FileExtension: TBCComboBox;
     CheckBox_UseDirectoryOnStartup: TCheckBox;
     DirectoryEdit1: TEdit;
@@ -174,7 +174,7 @@ uses BGRAThumbnail, BGRAPaintNet, BGRAOpenRaster, BGRAReadLzp,
     UConfig, bgrareadjpeg, FPReadJPEG,
     UFileExtensions, BGRAUTF8, LazFileUtils,
     UGraph, URaw, UDarkTheme, ShellCtrls,
-    UIconCache;
+    UIconCache, LCScaleDPI;
 
 { TFBrowseImages }
 
@@ -258,7 +258,7 @@ begin
 end;
 
 procedure TFBrowseImages.FormCreate(Sender: TObject);
-var bmp : TBitmap; delta: integer;
+var bmp : TBitmap;
 begin
   FLastDirectory := '';
   FOverwritePrompt:= true;
@@ -268,6 +268,12 @@ begin
   FPreview.OnValidate:= @PreviewValidate;
   FChosenImage := TImageEntry.Empty;
 
+  ScaleImageList(ImageListToolbar, DoScaleX(32, OriginalDPI),
+    DoScaleY(32, OriginalDPI), ImageListToolbar);
+
+  ScaleControl(Panel1, OriginalDPI, 0,0, true);
+  ScaleControl(Panel2, OriginalDPI, 0,0, true);
+
   DarkThemeInstance.Apply(ComboBox_FileExtension, False, 0.40);
   vsList.BitmapAutoScale:= false;
 
@@ -303,20 +309,12 @@ begin
   BGRAPaintNet.RegisterPaintNetFormat;
   BGRAOpenRaster.RegisterOpenRasterFormat;
 
-  if FileManager.CanGetFileSystems then
-  begin
-    Tool_SelectDrive.Visible := true;
-  end else
-  begin
-    Tool_SelectDrive.Visible := false;
-    delta := ImageListToolbar.Width+Toolbar1.Indent;
-    ToolBar1.Width := ToolBar1.Width-delta;
-    DirectoryEdit1.Left := DirectoryEdit1.Left-delta;
-    DirectoryEdit1.Width := DirectoryEdit1.Width+delta;
-  end;
+  Tool_SelectDrive.Visible := FileManager.CanGetFileSystems;
+  Toolbar1.AutoSize := true;
 
   FCreateFolderOrContainerCaption := ToolButton_CreateFolderOrContainer.Hint;
   ToolButton_CreateFolderOrContainer.Hint := ToolButton_CreateFolderOrContainer.Hint + '...';
+  ComboBox_FileExtension.TabStop := true;
 end;
 
 procedure TFBrowseImages.FormDestroy(Sender: TObject);
@@ -374,6 +372,12 @@ begin
   begin
     DeleteSelectedFiles;
     Key := 0;
+  end else
+  if (KEY = VK_F5) then
+  begin
+    ResetDirectory(false, true);
+    SelectFile(Edit_Filename.Text);
+    Key := 0;
   end;
 end;
 
@@ -383,11 +387,16 @@ begin
 end;
 
 procedure TFBrowseImages.FormShow(Sender: TObject);
-var r:TRect; i: integer;
+var r:TRect; i, delta: integer;
 begin
   if FInFormShow then exit;
   FInFormShow:= true;
 
+  delta := DirectoryEdit1.Left - (Toolbar1.Left + Toolbar1.Width
+    + DoScaleX(4, OriginalDPI));
+  DirectoryEdit1.Left := DirectoryEdit1.Left-delta;
+  DirectoryEdit1.Width := DirectoryEdit1.Width+delta;
+
   BGRAThumbnail.CheckersScale:= GetCanvasScaleFactor;
   ShellListView1.FontHeight:= ScaleY(round(13*GetCanvasScaleFactor),OriginalDPI);
   ShellListView1.SmallIconSize := round(ScaleX(round(64*GetCanvasScaleFactor),OriginalDPI)/16)*16;

+ 2 - 1
lazpaint/dialog/ulayerstackinterface.pas

@@ -166,6 +166,7 @@ end;
 procedure TLayerStackInterface.BGRALayerStack_Redraw(Sender: TObject;
   Bitmap: TBGRABitmap);
 begin
+  TVolatileScrollBar.InitDPI((Sender as TControl).GetCanvasScaleFactor);
   DrawLayerStack(Bitmap, not FPartialRedraw, -1);
 end;
 
@@ -912,8 +913,8 @@ begin
     FDontUpdateStack := true;
     LazPaintInstance.Image.BlendOperation[LazPaintInstance.Image.CurrentLayerIndex] := blendOp;
     FDontUpdateStack := false;
-    UpdateComboBlendOp;
   end;
+  UpdateComboBlendOp;
   tempUnder.Free;
   LazPaintInstance.ShowTopmost(topmostInfo);
   if LazPaintInstance.Image.CurrentLayerIndex = 0 then

+ 46 - 172
lazpaint/dialog/unewimage.lfm

@@ -12,7 +12,7 @@ object FNewImage: TFNewImage
   OnCreate = FormCreate
   OnShow = FormShow
   Position = poOwnerFormCenter
-  LCLVersion = '1.8.2.0'
+  LCLVersion = '2.0.10.0'
   object Label_Width: TLabel
     Left = 16
     Height = 15
@@ -37,7 +37,7 @@ object FNewImage: TFNewImage
     Caption = 'OK'
     Default = True
     OnClick = Button_OKClick
-    TabOrder = 6
+    TabOrder = 5
   end
   object Button_Cancel: TButton
     Left = 152
@@ -47,7 +47,7 @@ object FNewImage: TFNewImage
     Cancel = True
     Caption = 'Cancel'
     ModalResult = 2
-    TabOrder = 7
+    TabOrder = 6
   end
   object SpinEdit_Width: TSpinEdit
     Left = 80
@@ -80,24 +80,29 @@ object FNewImage: TFNewImage
     Width = 134
     OnRedraw = vsPreviewRedraw
     Alignment = taLeftJustify
+    ClientHeight = 128
+    ClientWidth = 134
     Color = clForm
     ParentColor = False
     TabOrder = 4
-  end
-  object ToolBar_Rotate: TToolBar
-    Left = 104
-    Height = 24
-    Top = 73
-    Width = 24
-    Align = alNone
-    EdgeBorders = []
-    Images = FMain.ImageList16
-    TabOrder = 5
-    object ToolButton_Rotate: TToolButton
-      Left = 1
-      Top = 0
-      ImageIndex = 43
-      OnClick = ToolButton_RotateClick
+    object ToolBar_Rotate: TToolBar
+      Left = 51
+      Height = 22
+      Top = 49
+      Width = 24
+      Align = alNone
+      AutoSize = True
+      Color = clForm
+      EdgeBorders = []
+      Images = FMain.ImageList16
+      ParentColor = False
+      TabOrder = 0
+      object ToolButton_Rotate: TToolButton
+        Left = 1
+        Top = 0
+        ImageIndex = 43
+        OnClick = ToolButton_RotateClick
+      end
     end
   end
   object Label_Height1: TLabel
@@ -112,7 +117,7 @@ object FNewImage: TFNewImage
     Left = 80
     Height = 23
     Top = 103
-    Width = 79
+    Width = 63
     ItemHeight = 15
     Items.Strings = (
       ''
@@ -121,11 +126,11 @@ object FNewImage: TFNewImage
       '5:4'
       '4:3'
       '11:8'
-      '1.4142:1'
+      '1.414:1'
       '1.43:1'
       '3:2'
       '8:5'
-      '1.6180:1'
+      '1.618:1'
       '5:3'
       '16:9'
       '2:1'
@@ -146,31 +151,16 @@ object FNewImage: TFNewImage
     BorderOpacity = 180
     BorderColor = clBlack
     BorderGradient.StartColor = clWhite
-    BorderGradient.StartColorOpacity = 255
-    BorderGradient.DrawMode = dmSet
     BorderGradient.EndColor = clBlack
-    BorderGradient.EndColorOpacity = 255
-    BorderGradient.ColorCorrection = True
     BorderGradient.GradientType = gtLinear
-    BorderGradient.Point1XPercent = 0
-    BorderGradient.Point1YPercent = 0
     BorderGradient.Point2XPercent = 100
     BorderGradient.Point2YPercent = 100
-    BorderGradient.Sinus = False
     FillColor = clBlack
     FillOpacity = 255
     FillGradient.StartColor = clWhite
-    FillGradient.StartColorOpacity = 255
-    FillGradient.DrawMode = dmSet
     FillGradient.EndColor = clBlack
-    FillGradient.EndColorOpacity = 255
-    FillGradient.ColorCorrection = True
     FillGradient.GradientType = gtLinear
-    FillGradient.Point1XPercent = 0
-    FillGradient.Point1YPercent = 0
-    FillGradient.Point2XPercent = 0
     FillGradient.Point2YPercent = 100
-    FillGradient.Sinus = False
     Caption = 'BGRAShape1'
     RoundRadius = 5
     OnClick = BGRAShapeClick
@@ -185,31 +175,16 @@ object FNewImage: TFNewImage
     BorderOpacity = 180
     BorderColor = clBlack
     BorderGradient.StartColor = clWhite
-    BorderGradient.StartColorOpacity = 255
-    BorderGradient.DrawMode = dmSet
     BorderGradient.EndColor = clBlack
-    BorderGradient.EndColorOpacity = 255
-    BorderGradient.ColorCorrection = True
     BorderGradient.GradientType = gtLinear
-    BorderGradient.Point1XPercent = 0
-    BorderGradient.Point1YPercent = 0
     BorderGradient.Point2XPercent = 100
     BorderGradient.Point2YPercent = 100
-    BorderGradient.Sinus = False
     FillColor = clBlue
     FillOpacity = 255
     FillGradient.StartColor = clWhite
-    FillGradient.StartColorOpacity = 255
-    FillGradient.DrawMode = dmSet
     FillGradient.EndColor = clBlack
-    FillGradient.EndColorOpacity = 255
-    FillGradient.ColorCorrection = True
     FillGradient.GradientType = gtLinear
-    FillGradient.Point1XPercent = 0
-    FillGradient.Point1YPercent = 0
-    FillGradient.Point2XPercent = 0
     FillGradient.Point2YPercent = 100
-    FillGradient.Sinus = False
     Caption = 'BGRAShape2'
     RoundRadius = 5
     OnClick = BGRAShapeClick
@@ -224,31 +199,16 @@ object FNewImage: TFNewImage
     BorderOpacity = 180
     BorderColor = clBlack
     BorderGradient.StartColor = clWhite
-    BorderGradient.StartColorOpacity = 255
-    BorderGradient.DrawMode = dmSet
     BorderGradient.EndColor = clBlack
-    BorderGradient.EndColorOpacity = 255
-    BorderGradient.ColorCorrection = True
     BorderGradient.GradientType = gtLinear
-    BorderGradient.Point1XPercent = 0
-    BorderGradient.Point1YPercent = 0
     BorderGradient.Point2XPercent = 100
     BorderGradient.Point2YPercent = 100
-    BorderGradient.Sinus = False
     FillColor = clRed
     FillOpacity = 255
     FillGradient.StartColor = clWhite
-    FillGradient.StartColorOpacity = 255
-    FillGradient.DrawMode = dmSet
     FillGradient.EndColor = clBlack
-    FillGradient.EndColorOpacity = 255
-    FillGradient.ColorCorrection = True
     FillGradient.GradientType = gtLinear
-    FillGradient.Point1XPercent = 0
-    FillGradient.Point1YPercent = 0
-    FillGradient.Point2XPercent = 0
     FillGradient.Point2YPercent = 100
-    FillGradient.Sinus = False
     Caption = 'BGRAShape3'
     RoundRadius = 5
     OnClick = BGRAShapeClick
@@ -263,31 +223,16 @@ object FNewImage: TFNewImage
     BorderOpacity = 180
     BorderColor = clBlack
     BorderGradient.StartColor = clWhite
-    BorderGradient.StartColorOpacity = 255
-    BorderGradient.DrawMode = dmSet
     BorderGradient.EndColor = clBlack
-    BorderGradient.EndColorOpacity = 255
-    BorderGradient.ColorCorrection = True
     BorderGradient.GradientType = gtLinear
-    BorderGradient.Point1XPercent = 0
-    BorderGradient.Point1YPercent = 0
     BorderGradient.Point2XPercent = 100
     BorderGradient.Point2YPercent = 100
-    BorderGradient.Sinus = False
     FillColor = clLime
     FillOpacity = 255
     FillGradient.StartColor = clWhite
-    FillGradient.StartColorOpacity = 255
-    FillGradient.DrawMode = dmSet
     FillGradient.EndColor = clBlack
-    FillGradient.EndColorOpacity = 255
-    FillGradient.ColorCorrection = True
     FillGradient.GradientType = gtLinear
-    FillGradient.Point1XPercent = 0
-    FillGradient.Point1YPercent = 0
-    FillGradient.Point2XPercent = 0
     FillGradient.Point2YPercent = 100
-    FillGradient.Sinus = False
     Caption = 'BGRAShape4'
     RoundRadius = 5
     OnClick = BGRAShapeClick
@@ -302,31 +247,16 @@ object FNewImage: TFNewImage
     BorderOpacity = 180
     BorderColor = clBlack
     BorderGradient.StartColor = clWhite
-    BorderGradient.StartColorOpacity = 255
-    BorderGradient.DrawMode = dmSet
     BorderGradient.EndColor = clBlack
-    BorderGradient.EndColorOpacity = 255
-    BorderGradient.ColorCorrection = True
     BorderGradient.GradientType = gtLinear
-    BorderGradient.Point1XPercent = 0
-    BorderGradient.Point1YPercent = 0
     BorderGradient.Point2XPercent = 100
     BorderGradient.Point2YPercent = 100
-    BorderGradient.Sinus = False
     FillColor = clFuchsia
     FillOpacity = 255
     FillGradient.StartColor = clWhite
-    FillGradient.StartColorOpacity = 255
-    FillGradient.DrawMode = dmSet
     FillGradient.EndColor = clBlack
-    FillGradient.EndColorOpacity = 255
-    FillGradient.ColorCorrection = True
     FillGradient.GradientType = gtLinear
-    FillGradient.Point1XPercent = 0
-    FillGradient.Point1YPercent = 0
-    FillGradient.Point2XPercent = 0
     FillGradient.Point2YPercent = 100
-    FillGradient.Sinus = False
     Caption = 'BGRAShape5'
     RoundRadius = 5
     OnClick = BGRAShapeClick
@@ -341,31 +271,16 @@ object FNewImage: TFNewImage
     BorderOpacity = 180
     BorderColor = clBlack
     BorderGradient.StartColor = clWhite
-    BorderGradient.StartColorOpacity = 255
-    BorderGradient.DrawMode = dmSet
     BorderGradient.EndColor = clBlack
-    BorderGradient.EndColorOpacity = 255
-    BorderGradient.ColorCorrection = True
     BorderGradient.GradientType = gtLinear
-    BorderGradient.Point1XPercent = 0
-    BorderGradient.Point1YPercent = 0
     BorderGradient.Point2XPercent = 100
     BorderGradient.Point2YPercent = 100
-    BorderGradient.Sinus = False
     FillColor = clAqua
     FillOpacity = 255
     FillGradient.StartColor = clWhite
-    FillGradient.StartColorOpacity = 255
-    FillGradient.DrawMode = dmSet
     FillGradient.EndColor = clBlack
-    FillGradient.EndColorOpacity = 255
-    FillGradient.ColorCorrection = True
     FillGradient.GradientType = gtLinear
-    FillGradient.Point1XPercent = 0
-    FillGradient.Point1YPercent = 0
-    FillGradient.Point2XPercent = 0
     FillGradient.Point2YPercent = 100
-    FillGradient.Sinus = False
     Caption = 'BGRAShape6'
     RoundRadius = 5
     OnClick = BGRAShapeClick
@@ -380,31 +295,16 @@ object FNewImage: TFNewImage
     BorderOpacity = 180
     BorderColor = clBlack
     BorderGradient.StartColor = clWhite
-    BorderGradient.StartColorOpacity = 255
-    BorderGradient.DrawMode = dmSet
     BorderGradient.EndColor = clBlack
-    BorderGradient.EndColorOpacity = 255
-    BorderGradient.ColorCorrection = True
     BorderGradient.GradientType = gtLinear
-    BorderGradient.Point1XPercent = 0
-    BorderGradient.Point1YPercent = 0
     BorderGradient.Point2XPercent = 100
     BorderGradient.Point2YPercent = 100
-    BorderGradient.Sinus = False
     FillColor = clYellow
     FillOpacity = 255
     FillGradient.StartColor = clWhite
-    FillGradient.StartColorOpacity = 255
-    FillGradient.DrawMode = dmSet
     FillGradient.EndColor = clBlack
-    FillGradient.EndColorOpacity = 255
-    FillGradient.ColorCorrection = True
     FillGradient.GradientType = gtLinear
-    FillGradient.Point1XPercent = 0
-    FillGradient.Point1YPercent = 0
-    FillGradient.Point2XPercent = 0
     FillGradient.Point2YPercent = 100
-    FillGradient.Sinus = False
     Caption = 'BGRAShape7'
     RoundRadius = 5
     OnClick = BGRAShapeClick
@@ -419,31 +319,16 @@ object FNewImage: TFNewImage
     BorderOpacity = 180
     BorderColor = clBlack
     BorderGradient.StartColor = clWhite
-    BorderGradient.StartColorOpacity = 255
-    BorderGradient.DrawMode = dmSet
     BorderGradient.EndColor = clBlack
-    BorderGradient.EndColorOpacity = 255
-    BorderGradient.ColorCorrection = True
     BorderGradient.GradientType = gtLinear
-    BorderGradient.Point1XPercent = 0
-    BorderGradient.Point1YPercent = 0
     BorderGradient.Point2XPercent = 100
     BorderGradient.Point2YPercent = 100
-    BorderGradient.Sinus = False
     FillColor = 11796479
     FillOpacity = 255
     FillGradient.StartColor = clWhite
-    FillGradient.StartColorOpacity = 255
-    FillGradient.DrawMode = dmSet
     FillGradient.EndColor = clBlack
-    FillGradient.EndColorOpacity = 255
-    FillGradient.ColorCorrection = True
     FillGradient.GradientType = gtLinear
-    FillGradient.Point1XPercent = 0
-    FillGradient.Point1YPercent = 0
-    FillGradient.Point2XPercent = 0
     FillGradient.Point2YPercent = 100
-    FillGradient.Sinus = False
     Caption = 'BGRAShape8'
     RoundRadius = 5
     OnClick = BGRAShapeClick
@@ -458,31 +343,16 @@ object FNewImage: TFNewImage
     BorderOpacity = 180
     BorderColor = clBlack
     BorderGradient.StartColor = clWhite
-    BorderGradient.StartColorOpacity = 255
-    BorderGradient.DrawMode = dmSet
     BorderGradient.EndColor = clBlack
-    BorderGradient.EndColorOpacity = 255
-    BorderGradient.ColorCorrection = True
     BorderGradient.GradientType = gtLinear
-    BorderGradient.Point1XPercent = 0
-    BorderGradient.Point1YPercent = 0
     BorderGradient.Point2XPercent = 100
     BorderGradient.Point2YPercent = 100
-    BorderGradient.Sinus = False
     FillColor = clWhite
     FillOpacity = 255
     FillGradient.StartColor = clWhite
-    FillGradient.StartColorOpacity = 255
-    FillGradient.DrawMode = dmSet
     FillGradient.EndColor = clBlack
-    FillGradient.EndColorOpacity = 255
-    FillGradient.ColorCorrection = True
     FillGradient.GradientType = gtLinear
-    FillGradient.Point1XPercent = 0
-    FillGradient.Point1YPercent = 0
-    FillGradient.Point2XPercent = 0
     FillGradient.Point2YPercent = 100
-    FillGradient.Sinus = False
     Caption = 'BGRAShape9'
     RoundRadius = 5
     OnClick = BGRAShapeClick
@@ -511,31 +381,16 @@ object FNewImage: TFNewImage
     BorderOpacity = 180
     BorderColor = clBlack
     BorderGradient.StartColor = clWhite
-    BorderGradient.StartColorOpacity = 255
-    BorderGradient.DrawMode = dmSet
     BorderGradient.EndColor = clBlack
-    BorderGradient.EndColorOpacity = 255
-    BorderGradient.ColorCorrection = True
     BorderGradient.GradientType = gtLinear
-    BorderGradient.Point1XPercent = 0
-    BorderGradient.Point1YPercent = 0
     BorderGradient.Point2XPercent = 100
     BorderGradient.Point2YPercent = 100
-    BorderGradient.Sinus = False
     FillColor = clWhite
     FillOpacity = 0
     FillGradient.StartColor = clWhite
-    FillGradient.StartColorOpacity = 255
-    FillGradient.DrawMode = dmSet
     FillGradient.EndColor = clBlack
-    FillGradient.EndColorOpacity = 255
-    FillGradient.ColorCorrection = True
     FillGradient.GradientType = gtLinear
-    FillGradient.Point1XPercent = 0
-    FillGradient.Point1YPercent = 0
-    FillGradient.Point2XPercent = 0
     FillGradient.Point2YPercent = 100
-    FillGradient.Sinus = False
     Caption = 'BGRAShape10'
     RoundRadius = 5
     OnClick = BGRAShapeClick
@@ -567,7 +422,7 @@ object FNewImage: TFNewImage
     Left = 80
     Height = 23
     Top = 72
-    Width = 79
+    Width = 63
     ItemHeight = 15
     ItemIndex = 5
     Items.Strings = (
@@ -584,4 +439,23 @@ object FNewImage: TFNewImage
     TabOrder = 2
     Text = '32'
   end
+  object ToolBar_Ratio: TToolBar
+    Left = 143
+    Height = 22
+    Top = 103
+    Width = 24
+    Align = alNone
+    AutoSize = True
+    Caption = 'ToolBar_Ratio'
+    EdgeBorders = []
+    Images = FMain.ImageList16
+    TabOrder = 7
+    object ToolButton_ClearRatio: TToolButton
+      Left = 1
+      Top = 0
+      Caption = 'ToolButton_ClearRatio'
+      ImageIndex = 39
+      OnClick = ToolButton_ClearRatioClick
+    end
+  end
 end

+ 13 - 0
lazpaint/dialog/unewimage.pas

@@ -38,7 +38,9 @@ type
     Label_MemoryRequiredValue: TLabel;
     Label_Height1: TLabel;
     Label_MemoryRequired: TLabel;
+    ToolBar_Ratio: TToolBar;
     ToolBar_Rotate: TToolBar;
+    ToolButton_ClearRatio: TToolButton;
     ToolButton_Rotate: TToolButton;
     vsPreview: TBGRAVirtualScreen;
     Button_OK: TButton;
@@ -53,6 +55,7 @@ type
     procedure ComboBox_RatioEnter(Sender: TObject);
     procedure ComboBox_RatioExit(Sender: TObject);
     procedure SpinEdit_HeightChange(Sender: TObject);
+    procedure ToolButton_ClearRatioClick(Sender: TObject);
     procedure ToolButton_RotateClick(Sender: TObject);
     procedure vsPreviewRedraw(Sender: TObject; Bitmap: TBGRABitmap);
     procedure Button_OKClick(Sender: TObject);
@@ -263,6 +266,12 @@ begin
   UpdatePreview;
 end;
 
+procedure TFNewImage.ToolButton_ClearRatioClick(Sender: TObject);
+begin
+  ComboBox_Ratio.ItemIndex:= 0;
+  ComboBox_RatioChange(ComboBox_Ratio);
+end;
+
 procedure TFNewImage.FormCreate(Sender: TObject);
 begin
   ScaleControl(Self,OriginalDPI);
@@ -282,6 +291,7 @@ end;
 procedure TFNewImage.FormShow(Sender: TObject);
 begin
   ToolBar_Rotate.Images := LazPaintInstance.Icons[DoScaleY(16,OriginalDPI)];
+  ToolBar_Ratio.Images := ToolBar_Rotate.Images;
   Label_MemoryRequiredValue.Left := Label_MemoryRequired.BoundsRect.Right + DoScaleX(4,OriginalDPI);
 
   FRecomputing := true;
@@ -342,6 +352,9 @@ procedure TFNewImage.UpdatePreview;
 begin
   vsPreview.DiscardBitmap;
   Label_MemoryRequiredValue.Caption := FileSizeToStr(int64((SpinEdit_Width.Value*GetBitDepth+7) div 8)*SpinEdit_Height.Value,rsBytes);
+  if FBackColor.alpha = 0 then
+    ToolBar_Rotate.Color := MergeBGRA(ColorToBGRA(clSilver), ColorToBGRA(clWhite))
+    else ToolBar_Rotate.Color := ColorToBGRA(FBackColor);
 end;
 
 function TFNewImage.GetBitDepth: integer;

+ 16 - 4
lazpaint/dialog/usaveoption.pas

@@ -179,6 +179,8 @@ begin
   FFlattenedOriginal := nil;
   FSizeCaption:= Label_Size.Caption;
   LayoutRadioButtonDepth;
+  BGRAPreview.BitmapAutoScale:= false;
+  BGRAPreview.Color := clGray;
 end;
 
 procedure TFSaveOption.FormDestroy(Sender: TObject);
@@ -274,10 +276,10 @@ end;
 
 procedure TFSaveOption.BGRAPreviewRedraw(Sender: TObject;
   Bitmap: TBGRABitmap);
-var ratioX,ratioY,ratio: single;
+var ratioX,ratioY,ratio, checkerScale: single;
   picture: TBGRABitmap;
   mustFreePic: boolean;
-  x,y,visualWidth,visualHeight: integer;
+  x,y,visualWidth,visualHeight,ofs: integer;
   r: TRect;
   thumb: TBGRABitmap;
 begin
@@ -333,7 +335,17 @@ begin
   if visualHeight < 1 then visualHeight:= 1;
   x := (Bitmap.Width-visualWidth) div 2;
   y := (Bitmap.Height-visualHeight) div 2;
-  r := rect(x,y,x+visualWidth,y+visualHeight);
+  r := RectWithSize(x, y, visualWidth, visualHeight);
+
+  checkerScale := DoScaleX(60, OriginalDPI)/60;
+  if not BGRAPreview.BitmapAutoScale then
+    checkerScale *= BGRAPreview.GetCanvasScaleFactor;
+  ofs := round(4*checkerScale);
+  if visualWidth < ofs then ofs := visualWidth;
+  if visualHeight < ofs then ofs := visualHeight;
+  bitmap.FillRect(rect(x+visualWidth,y+ofs,x+ofs+visualWidth,y+ofs+visualHeight), BGRA(0,0,0,128),dmDrawWithTransparency);
+  bitmap.FillRect(rect(x+ofs,y+visualHeight,x+visualWidth,y+ofs+visualHeight), BGRA(0,0,0,128),dmDrawWithTransparency);
+
   if ImageFormat in[ifIco,ifCur] then
   begin
     thumb := GetBitmapThumbnail(picture, ImageFormat, visualWidth,visualHeight, BGRAPixelTransparent, true);
@@ -341,7 +353,7 @@ begin
     thumb.Free;
   end else
   begin
-    DrawCheckers(Bitmap, r);
+    DrawCheckers(Bitmap, r, checkerScale);
     Bitmap.StretchPutImage(r, picture, dmDrawWithTransparency);
   end;
   if mustFreePic then picture.Free;

+ 3 - 3
lazpaint/lazpaint.lpi

@@ -24,7 +24,7 @@
       <UseVersionInfo Value="True"/>
       <MajorVersionNr Value="7"/>
       <MinorVersionNr Value="1"/>
-      <RevisionNr Value="4"/>
+      <RevisionNr Value="5"/>
       <CharSet Value="04B0"/>
       <StringTable CompanyName="http://sourceforge.net/projects/lazpaint/" FileDescription="LazPaint" InternalName="lazpaint" OriginalFilename="lazpaint.exe" ProductName="LazPaint"/>
     </VersionInfo>
@@ -334,11 +334,11 @@
     <RequiredPackages Count="5">
       <Item1>
         <PackageName Value="BGRABitmapPack"/>
-        <MinVersion Major="11" Minor="2" Release="4" Valid="True"/>
+        <MinVersion Major="11" Minor="2" Release="5" Valid="True"/>
       </Item1>
       <Item2>
         <PackageName Value="bgracontrols"/>
-        <MinVersion Major="6" Minor="9" Valid="True"/>
+        <MinVersion Major="7" Minor="0" Valid="True"/>
       </Item2>
       <Item3>
         <PackageName Value="lazpaintcontrols"/>

+ 1 - 1
lazpaint/lazpaintembeddedpack.lpk

@@ -26,7 +26,7 @@
         </Debugging>
       </Linking>
     </CompilerOptions>
-    <Version Major="7" Minor="1" Release="4"/>
+    <Version Major="7" Minor="1" Release="5"/>
     <Files Count="94">
       <Item1>
         <Filename Value="lazpaintinstance.pas"/>

+ 63 - 15
lazpaint/lazpaintinstance.pas

@@ -277,7 +277,7 @@ uses LCLType, Types, Forms, Dialogs, FileUtil, StdCtrls, LCLIntf, BGRAUTF8, UTra
      USharpen, uposterize, UPhongFilter, UFilterFunction,
      uprint, USaveOption, UFormRain,
 
-     ugraph, LCScaleDPI, ucommandline, uabout, UPython, UVolatileScrollBar;
+     ugraph, LCScaleDPI, ucommandline, uabout, UPython, BGRAGraphics;
 
 { TLazPaintInstance }
 
@@ -430,8 +430,6 @@ end;
 
 procedure TLazPaintInstance.Init(AEmbedded: boolean);
 begin
-  TVolatileScrollBar.InitDPI;
-
   Title := 'LazPaint ' + LazPaintCurrentVersion;
   FCustomImageList := TImageListList.Create;
   FTopMostInfo.choosecolorHidden := 0;
@@ -1252,37 +1250,87 @@ begin
 end;
 
 function TLazPaintInstance.GetIcons(ASize: integer): TImageList;
-var
-  i: Integer;
-begin
-  if Assigned(FMain) then
-  begin
-    for i := 0 to FCustomImageList.Count-1 do
-      if FCustomImageList[i].Height = ASize then
-        exit(FCustomImageList[i]);
 
+  function GetUnscaledIcons(ASize: integer): TImageList;
+  begin
     if ASize < 24 then
     begin;
       if ASize = 16 then
-        result := FMain.ImageList16
+      begin
+        result := TImageList.Create(nil);
+        result.Assign(FMain.ImageList16);
+      end
       else
       begin
         result := TImageList.Create(nil);
         ScaleImageList(FMain.ImageList16, ASize,ASize, result);
-        FCustomImageList.Add(result);
       end;
     end
     else
     begin
       if ASize = 48 then
-        result := FMain.ImageList48
+      begin
+        result := TImageList.Create(nil);
+        result.Assign(FMain.ImageList48);
+      end
       else
       begin
         result := TImageList.Create(nil);
         ScaleImageList(FMain.ImageList48, ASize,ASize, result);
-        FCustomImageList.Add(result);
       end;
     end;
+  end;
+
+var
+  i: Integer;
+  {$IFDEF DARWIN}
+  retina, unscaled: TImageList;
+  bmpUnscaled, bmpRetina: TBitmap;
+  {$ENDIF}
+
+begin
+  if Assigned(FMain) then
+  begin
+    for i := 0 to FCustomImageList.Count-1 do
+      if FCustomImageList[i].Height = ASize then
+        exit(FCustomImageList[i]);
+
+    {$IFDEF DARWIN}
+    unscaled := GetUnscaledIcons(ASize);
+    retina := GetUnscaledIcons(ASize*2);
+    bmpUnscaled := TBitmap.Create;
+    bmpRetina := TBitmap.Create;
+
+    result := TImageList.Create(nil);
+    result.Width := ASize;
+    result.Height := ASize;
+    result.Scaled := true;
+    result.RegisterResolutions([ASize, ASize*2]);
+    for i := 0 to unscaled.Count-1 do
+    begin
+      unscaled.GetBitmap(i, bmpUnscaled);
+      retina.GetBitmap(i, bmpRetina);
+      result.AddMultipleResolutions([bmpUnscaled, bmpRetina]);
+    end;
+
+    bmpUnscaled.Free;
+    bmpRetina.Free;
+    unscaled.Free;
+    retina.Free;
+    {$ELSE}
+    if ASize = 16 then
+    begin
+      result := FMain.ImageList16;
+      exit
+    end else
+    if ASize = 48 then
+    begin
+      result := FMain.ImageList48;
+      exit;
+    end else
+      result := GetUnscaledIcons(ASize);
+    {$ENDIF}
+    FCustomImageList.Add(result);
   end else
     result := nil;
 end;

+ 2 - 0
lazpaint/lazpaintmainform.lfm

@@ -3056,6 +3056,8 @@ object FMain: TFMain
         93794A89288EE7EDFD7151874569D446E3CAD0C6C25555FF01E3A570E78DDA12
         390000000049454E44AE426082
       }
+      Proportional = True
+      Stretch = True
     end
   end
   object Panel_BackFill: TPanel

+ 2 - 2
lazpaint/lazpaintmainform.pas

@@ -12,7 +12,7 @@ uses
 
   BGRABitmap, BGRABitmapTypes, BGRALayers, BGRASVGOriginal, BGRAGradientScanner, BGRAGradientOriginal,
 
-  LazPaintType, UMainFormLayout, UTool, UImage, UImageAction, UZoom, UImageView,
+  LazPaintType, UMainFormLayout, UTool, UImage, UImageAction, UZoom,
   UImageObservation, UConfig, LCScaleDPI, UResourceStrings, UMenu, uscripting,
   ubrowseimages, UToolPolygon, UToolVectorial, LCVectorRectShapes,
   LCVectorialFillControl, LCVectorialFill,
@@ -862,7 +862,7 @@ uses LCLIntf, BGRAUTF8, ugraph, math, umac, uclipboard, ucursors,
    ufilters, ULoadImage, ULoading, UFileExtensions, UBrushType,
    ugeometricbrush, UPreviewDialog, UQuestion, BGRALayerOriginal,
    BGRATransform, LCVectorPolyShapes, URaw, UFileSystem,
-   UTranslation, UPython;
+   UTranslation, UPython, BCTypes;
 
 const PenWidthFactor = 10;
 

+ 1 - 1
lazpaint/lazpainttype.pas

@@ -11,7 +11,7 @@ uses
   {$IFDEF LINUX}, InterfaceBase{$ENDIF};
 
 const
-  LazPaintVersion = 7010400;
+  LazPaintVersion = 7010500;
 
   function LazPaintVersionStr: string;
 

+ 4 - 0
lazpaint/maintoolbar.inc

@@ -65,15 +65,18 @@ begin
   ComboBox_ArrowStart.OnChange := @ComboBox_ArrowStartChange;
   ComboBox_ArrowStart.OnDrawItem := @ComboBox_ArrowStartDrawItem;
   ComboBox_ArrowStart.OnDrawSelectedItem := @ComboBox_ArrowStartDrawSelectedItem;
+  ComboBox_ArrowStart.CanvasScaleMode:= csmFullResolution;
   ComboBox_ArrowEnd.OnChange := @ComboBox_ArrowEndChange;
   ComboBox_ArrowEnd.OnDrawItem := @ComboBox_ArrowEndDrawItem;
   ComboBox_ArrowEnd.OnDrawSelectedItem := @ComboBox_ArrowEndDrawSelectedItem;
+  ComboBox_ArrowEnd.CanvasScaleMode:= csmFullResolution;
   Tool_JoinBevel.OnClick := @Tool_JoinBevelClick;
   Tool_JoinRound.OnClick := @Tool_JoinRoundClick;
   Tool_JoinMiter.OnClick := @Tool_JoinMiterClick;
   ComboBox_PenStyle.OnChange:=@ComboBox_PenStyleChange;
   ComboBox_PenStyle.OnDrawItem:=@ComboBox_PenStyleDrawItem;
   ComboBox_PenStyle.OnDrawSelectedItem:=@ComboBox_PenStyleDrawSelectedItem;
+  ComboBox_PenStyle.CanvasScaleMode:= csmFullResolution;
   for ps := psSolid to psDashDotDot do ComboBox_PenStyle.Items.Add(inttostr(ord(ps)));
   Tool_GridMoveWithoutDeformation.OnClick := @Tool_GridMoveWithoutDeformationClick;
   Combo_SplineStyle.Items.Add('Inside');
@@ -115,6 +118,7 @@ begin
   ComboBox_BrushSelect.OnChange := @ComboBox_BrushSelectChange;
   ComboBox_BrushSelect.OnDrawItem := @ComboBox_BrushSelectDrawItem;
   ComboBox_BrushSelect.OnDrawSelectedItem:= @ComboBox_BrushSelectDrawSelectedItem;
+  ComboBox_BrushSelect.CanvasScaleMode:= csmFullResolution;
   Combo_Ratio.OnChange := @Combo_RatioChange;
 
   Panel_LineCap_FullSize := Panel_LineCap.Width;

+ 13 - 0
lazpaint/release/debian/debian/changelog

@@ -1,3 +1,16 @@
+lazpaint (7.1.5) stable; urgency=low
+
+  * image browser: can move to trash on MacOS
+  * image browser: F5 to update file list
+  * image browser: fix tab stops
+  * macOS: scaling of icons, comboboxes and buttons
+  * comboboxes: fix scaling and non responsive drop down
+  * checkers: scaled according to DPI
+  * file new: add icon to discard ratio
+  * top toolbar: stretch switch color button to DPI
+
+ -- circular <[email protected]>  Sun, 18 Oct 2020 21:51:00 +0100
+  
 lazpaint (7.1.4) stable; urgency=low
 
   * add --help command line

+ 1 - 1
lazpaint/release/debian/debian/control

@@ -6,7 +6,7 @@ Build-Depends: lazarus-project (>= 2.0.2), dpkg-dev (>= 7)
 Homepage: https://wiki.freepascal.org/LazPaint
 Package: lazpaint
 Architecture: any
-Version: 7.1.4
+Version: 7.1.5
 Depends: ${shlibs:Depends}
 Description: Graphics viewer and editor. 
  Can read layered files (lzp, ora, pdn, oXo), multi-images (gif, ico, tiff), 

+ 2 - 0
lazpaint/release/debian/makedeb.sh

@@ -1,4 +1,6 @@
 #!/bin/bash
+cd `dirname $0`
+
 STAGING_RELATIVEDIR="./staging"
 STAGING_DIR=$(readlink --canonicalize "${STAGING_RELATIVEDIR}")
 USER_DIR="${STAGING_DIR}/usr"

+ 2 - 2
lazpaint/release/macOS/LazPaint.app/Contents/Info.plist

@@ -19,9 +19,9 @@
     <key>CFBundleSignature</key>
     <string>lazp</string>
     <key>CFBundleShortVersionString</key>
-    <string>7.1.4</string>
+    <string>7.1.5</string>
     <key>CFBundleVersion</key>
-    <string>7.1.4</string>
+    <string>7.1.5</string>
     <key>CSResourcesFileMapped</key>
     <true/>
     <key>CFBundleDocumentTypes</key>

+ 2 - 6
lazpaint/release/macOS/makedmg.sh

@@ -1,18 +1,14 @@
 #!/bin/bash
 set -e
+cd `dirname $0`
 
 if ! [ ${OSTYPE:0:6} = "darwin" ]; then
   echo "This script is for OS X only"
   exit 1
 fi
 
-if [ -e "macOS" ]; then
-  rm -R macOS
-fi
-
-
 appname=LazPaint
-appversion=7.1.4
+appversion=7.1.5
 pkgversion=0
 appnamenospaces=lazpaint
 appbundle="$appname.app"

+ 1 - 1
lazpaint/release/windows/lazpaint.iss

@@ -1,7 +1,7 @@
 #define MyAppName "LazPaint"
 #define MyAppOutputName "lazpaint"
 #define MyInstallerSuffix "_setup_win32_win64"
-#define MyAppVersion "7.1.4"
+#define MyAppVersion "7.1.5"
 #define MyAppPublisher "Circular, Fabien Wang, Lainz and others"
 #define MyAppURL "http://sourceforge.net/projects/lazpaint/"
 #define MyAppExeName "lazpaint.exe"

+ 3 - 0
lazpaint/udarktheme.pas

@@ -400,6 +400,7 @@ begin
   Apply(ACombo.Button, ADarkTheme, AFontHeightRatio);
   with ACombo do
   begin
+    FocusBorderOpacity:= 128;
     fh := round((Height+4)*AFontHeightRatio);
     Button.StateNormal.FontEx.Height := fh;
     Button.StateNormal.FontEx.ShadowColorOpacity:= 96;
@@ -412,11 +413,13 @@ begin
       DropDownBorderColor:= clBlack;
       DropDownFontColor:= clLightText;
       DropDownColor:= clDarkBtnFace;
+      FocusBorderColor:= clLightText;
     end else
     begin
       DropDownBorderColor := MergeBGRA(ColorToBGRA(clWindowText),ColorToBGRA(clWindow));
       DropDownFontColor:= clWindowText;
       DropDownColor:= clWindow;
+      FocusBorderColor:= clWindowText;
     end;
     DropDownFontHighlight:= clHighlightText;
     DropDownHighlight:= clHighlight;

+ 65 - 4
lazpaint/ufilesystem.pas

@@ -543,6 +543,56 @@ begin
 end;
 {$ENDIF}
 
+{$IFDEF DARWIN}
+function RunAppleScriptLine(AScriptLine: string): boolean;
+var
+  p: TProcess;
+begin
+  p := nil;
+  try
+    p := TProcess.Create(nil);
+    p.Executable := 'osascript';
+    p.Parameters.Add('-e');
+    p.Parameters.Add(AScriptLine);
+    p.Options := [poWaitOnExit];
+    p.Execute;
+    result := true;
+  except
+    result := false;
+  end;
+  p.Free;
+end;
+
+function AppleScriptEscape(AText: string): string;
+begin
+  result := StringReplace(AText, '\', '\\', [rfReplaceAll]);
+  result := StringReplace(result, '"', '\"', [rfReplaceAll]);
+end;
+
+function MoveToTrashOnMacOS(AForm: TForm; const AFilenamesUTF8: array of string; AConfirmationCallback: TDeleteConfirmationFunction): boolean;
+var
+  appleScript: String;
+  i: Integer;
+begin
+  if length(AFilenamesUTF8) = 0 then exit(true);
+  if Assigned(AConfirmationCallback) then
+  begin
+    if not AConfirmationCallback(AForm, AFilenamesUTF8, False) then exit(false);
+  end;
+  appleScript := 'tell application "Finder" to delete {';
+  for i := 0 to high(AFilenamesUTF8) do
+  begin
+    if i > 0 then appleScript += ', ';
+    appleScript += 'POSIX file "' + AppleScriptEscape(AFilenamesUTF8[i]) + '"';
+  end;
+  appleScript += '}';
+  if not RunAppleScriptLine(appleScript) then exit(false);
+  result := true;
+  for i := 0 to high(AFilenamesUTF8) do
+    if FileExists(AFilenamesUTF8[i]) then result := false;
+end;
+{$ENDIF}
+
 function IsMultiFileContainerName(AFilenameUTF8: string): boolean;
 var
   ext: String;
@@ -600,9 +650,16 @@ begin
   setlength(containedFiles, nbContainedFiles);
   if nbContainedFiles > 0 then
   begin
-    if not AConfirmationCallback(AForm, containedFiles, True) then exit;
-    for i := 0 to high(containedFiles) do
-      DeleteFile(containedFiles[i]);
+    if not AConfirmationCallback(AForm, containedFiles, True) then exit(false);
+    try
+      for i := 0 to high(containedFiles) do
+        DeleteFile(containedFiles[i]);
+    except on ex: exception do
+      begin
+        ShowMessage(ex.Message);
+        exit(false);
+      end;
+    end;
   end;
   if nbRealFiles > 0 then
   begin
@@ -612,7 +669,11 @@ begin
       {$IFDEF WINDOWS}
       result := MoveToTrashOnWindows(AForm, realFiles, AConfirmationCallback);
       {$ELSE}
-      result := false;
+        {$IFDEF DARWIN}
+        result := MoveToTrashOnMacOS(AForm, realFiles, AConfirmationCallback);
+        {$ELSE}
+        result := false;
+        {$ENDIF}
       {$ENDIF}
     {$ENDIF}
   end;

+ 9 - 5
lazpaint/ugraph.pas

@@ -792,6 +792,7 @@ procedure DrawPenStyle(AComboBox: TBCComboBox; ARect: TRect;
   APenStyle: TPenStyle; State: TOwnerDrawState);
 var bmp : TBGRABitmap;
   c,c2: TBGRAPixel;
+  scale: Double;
 begin
   if odSelected in State then
   begin
@@ -803,9 +804,10 @@ begin
     c := ColorToBGRA(AComboBox.DropDownFontColor);
     c2 := ColorToBGRA(AComboBox.DropDownColor);
   end;
-  with Size(ARect) do bmp := TBGRABitmap.Create(cx,cy,c2);
-  DrawPenStyle(bmp, rect(0,0,ARect.Width,ARect.Height),APenStyle, c);
-  bmp.Draw(ACombobox.Canvas,ARect.Left,ARect.Top,true);
+  scale := AComboBox.GetCanvasScaleFactor;
+  with Size(ARect) do bmp := TBGRABitmap.Create(round(cx*scale),round(cy*scale),c2);
+  DrawPenStyle(bmp, bmp.ClipRect,APenStyle, c);
+  bmp.Draw(ACombobox.Canvas,ARect,true);
   bmp.Free;
 end;
 
@@ -821,6 +823,7 @@ end;
 procedure DrawArrow(AComboBox: TBCComboBox; ARect: TRect; AStart: boolean; AKindStr: string; ALineCap: TPenEndCap; State: TOwnerDrawState);
 var mask, bmp : TBGRABitmap;
   c,c2: TBGRAPixel;
+  scale: Double;
 begin
   if odSelected in State then
   begin
@@ -831,11 +834,12 @@ begin
     c2 := ColorToBGRA(AComboBox.DropDownColor);
     c := ColorToBGRA(AComboBox.DropDownFontColor);
   end;
-  with Size(ARect) do mask:= TBGRABitmap.Create(cx,cy,BGRABlack);
+  scale := AComboBox.GetCanvasScaleFactor;
+  with Size(ARect) do mask:= TBGRABitmap.Create(round(cx*scale),round(cy*scale),BGRABlack);
   DrawArrowMask(mask, AStart, AKindStr, ALineCap);
   bmp := TBGRABitmap.Create(mask.Width,mask.Height,c2);
   bmp.FillMask(0,0,mask,c,dmDrawWithTransparency);
-  bmp.Draw(ACombobox.Canvas,ARect.Left,ARect.Top,true);
+  bmp.Draw(ACombobox.Canvas,ARect,true);
   bmp.Free;
   mask.Free;
 end;

+ 6 - 3
lazpaint/uimagepreview.pas

@@ -110,7 +110,7 @@ type
 implementation
 
 uses FPimage, BGRAReadJpeg, BGRAOpenRaster, BGRAPaintNet, BGRAReadLzp, Dialogs, UNewimage,
-  LCLType, BGRAPhoxo, BGRASVG, math, URaw, UImage;
+  LCLType, BGRAPhoxo, BGRASVG, math, URaw, UImage, LCScaleDPI;
 
 { TImagePreview }
 
@@ -140,6 +140,7 @@ end;
 procedure TImagePreview.SurfaceRedraw(Sender: TObject; Bitmap: TBGRABitmap);
 begin
   FScaling := FSurface.GetCanvasScaleFactor;
+  TVolatileScrollBar.InitDPI(FScaling);
   FSurfaceScaledHeight := Bitmap.Height;
   if (Bitmap.Width = 0) or (Bitmap.Height = 0) then
   begin
@@ -304,6 +305,7 @@ end;
 procedure TImagePreview.DrawCurrentFrame(Bitmap: TBGRABitmap);
 var x,y,w,h,ofs: integer;
   frame: TBGRABitmap;
+  checkerScale: single;
 begin
   ClearMenu;
   frame := GetCurrentFrameBitmap;
@@ -330,13 +332,14 @@ begin
   end;
   x := (bitmap.Width-w) div 2;
   y := (bitmap.Height-h) div 2;
-  ofs := 4;
+  checkerScale := DoScaleX(round(60*FScaling), OriginalDPI)/60;
+  ofs := round(4*checkerScale);
   if w < ofs then ofs := w;
   if h < ofs then ofs := h;
   bitmap.FillRect(rect(x+w,y+ofs,x+ofs+w,y+ofs+h), BGRA(0,0,0,128),dmDrawWithTransparency);
   bitmap.FillRect(rect(x+ofs,y+h,x+w,y+ofs+h), BGRA(0,0,0,128),dmDrawWithTransparency);
 
-  DrawThumbnailCheckers(Bitmap, rect(x,y,x+w,y+h), false, FScaling);
+  DrawThumbnailCheckers(Bitmap, rect(x,y,x+w,y+h), false, checkerScale);
   bitmap.StretchPutImage(rect(x,y,x+w,y+h), frame, dmDrawWithTransparency)
 end;
 

+ 1 - 1
lazpaint/uimageview.pas

@@ -467,7 +467,7 @@ begin
       OffsetRect(renderRect, -FLastPictureParameters.scaledVirtualScreenArea.Left,
                              -FLastPictureParameters.scaledVirtualScreenArea.Top);
 
-      DrawThumbnailCheckers(FVirtualScreen, renderRect, Image.IsIconCursor, CanvasScale);
+      DrawThumbnailCheckers(FVirtualScreen, renderRect, Image.IsIconCursor, DoScaleX(60*CanvasScale, OriginalDPI)/60);
 
       //draw image (with merged selection)
       FVirtualScreen.StretchPutImage(renderRect,Image.RenderedImage,dmDrawWithTransparency);

+ 12 - 16
lazpaint/umyslv.pas

@@ -539,15 +539,9 @@ var
       FVScrollBar := TVolatileScrollBar.Create(w-VolatileScrollBarSize,textHeight,
          VolatileScrollBarSize,h-textHeight,sbVertical,FVerticalScrollPos,0,maxScroll);
     end;
-    if Assigned(FVScrollBar) then
-    begin
-      FVScrollBar.Draw(ABitmap);
-      clientArea := rect(0,textHeight,w-VolatileScrollBarSize,h);
-    end else
-    begin
-      clientArea := rect(0,textHeight,w,h);
+    if not Assigned(FVScrollBar) then
       FVerticalScrollPos:= 0;
-    end;
+    clientArea := rect(0,textHeight,w,h);
     FItemsPerPage:= Size(clientArea).cy div FActualRowHeight;
 
     setlength(colPos,ColumnCount+1);
@@ -603,6 +597,10 @@ var
       inc(curY, FActualRowHeight);
       inc(row);
     end;
+    ABitmap.NoClip;
+
+    if Assigned(FVScrollBar) then
+      FVScrollBar.Draw(ABitmap);
   end;
 
   procedure DrawIcons;
@@ -632,15 +630,9 @@ var
       FVScrollBar := TVolatileScrollBar.Create(w-VolatileScrollBarSize,0,
          VolatileScrollBarSize,h,sbVertical,FVerticalScrollPos,0,maxScroll);
     end;
-    if Assigned(FVScrollBar) then
-    begin
-      FVScrollBar.Draw(ABitmap);
-      clientArea := rect(0,0,w-VolatileScrollBarSize,h);
-    end else
-    begin
-      clientArea := rect(0,0,w,h);
+    if not Assigned(FVScrollBar) then
       FVerticalScrollPos := 0;
-    end;
+    clientArea := rect(0,0,w,h);
     FItemsPerPage:= (Size(clientArea).cy div totalIconVSize)*FIconsPerLine;
     for item := 0 to ItemCount-1 do SetDisplayRect(item,EmptyRect);
     item := (FVerticalScrollPos div (32*FIconsPerLine))*FIconsPerLine;
@@ -687,11 +679,15 @@ var
       end;
       inc(item);
     end;
+    if Assigned(FVScrollBar) then
+      FVScrollBar.Draw(ABitmap);
   end;
 
 var i: integer;
 
 begin
+  TVolatileScrollBar.InitDPI((Sender as TControl).GetCanvasScaleFactor);
+
   if SelectedIndex = -1 then FKeySelectionRangeStart := -1
   else if FKeySelectionRangeStart = -1 then FKeySelectionRangeStart:= SelectedIndex;
   for i := 0 to ColumnCount-1 do

+ 15 - 4
lazpaint/upalettetoolbar.pas

@@ -45,6 +45,7 @@ type
     FLazPaintInstance: TLazPaintCustomInstance;
     FOnVisibilityChangedByUser: TPaletteVisibilityChangedByUserHandler;
     FPanelPalette: TBGRAVirtualScreen;
+    FCanvasScale: single;
     FVisible: boolean;
     FScrollbar: TVolatileScrollBar;
     FScrollPos: integer;
@@ -132,6 +133,8 @@ end;
 procedure TPaletteToolbar.PanelMouseDown(Sender: TObject; Button: TMouseButton;
   Shift: TShiftState; X, Y: Integer);
 begin
+  X := round(X*FCanvasScale);
+  Y := round(Y*FCanvasScale);
   if (Button = mbLeft) and Assigned(FScrollbar) then
   begin
     if FScrollbar.MouseDown(X,Y) then
@@ -147,6 +150,8 @@ end;
 procedure TPaletteToolbar.PanelMouseMove(Sender: TObject; Shift: TShiftState;
   X, Y: Integer);
 begin
+  X := round(X*FCanvasScale);
+  Y := round(Y*FCanvasScale);
   if Assigned(FScrollbar) then
   begin
     if FScrollbar.MouseMove(X,Y) then
@@ -166,6 +171,8 @@ end;
 procedure TPaletteToolbar.PanelMouseUp(Sender: TObject; Button: TMouseButton;
   Shift: TShiftState; X, Y: Integer);
 begin
+  X := round(X*FCanvasScale);
+  Y := round(Y*FCanvasScale);
   if (Button = mbLeft) and Assigned(FScrollbar) then
   begin
     if FScrollbar.MouseUp(X,Y) then
@@ -481,6 +488,7 @@ begin
     FPanelPalette.OnMouseDown:=@PanelMouseDown;
     FPanelPalette.OnMouseUp:=@PanelMouseUp;
     FPanelPalette.OnMouseMove:=@PanelMouseMove;
+    FPanelPalette.BitmapAutoScale:= false;
     ApplyTheme;
     FPanelPalette.Caption := '';
     FColors := TBGRAPalette.Create;
@@ -730,6 +738,9 @@ var i,x,y,w,aw,a,h: integer;
   nbVisible, maxScroll, availHeight: integer;
   clInterm, cSign: TBGRAPixel;
 begin
+  FCanvasScale := (Sender as TControl).GetCanvasScaleFactor;
+  TVolatileScrollBar.InitDPI(FCanvasScale);
+
   if DarkTheme then
   begin
     clInterm := MergeBGRA(ColorToBGRA(clDarkBtnFace),ColorToBGRA(clLightText));
@@ -739,11 +750,11 @@ begin
   else
     clInterm := MergeBGRA(ColorToBGRA(ColorToRGB(clBtnFace)),ColorToBGRA(ColorToRGB(clBtnText)));
 
-  x := 2;
-  y := FMenuButton.Top+FMenuButton.Height+1;
+  x := round(2*FCanvasScale);
+  y := round((FMenuButton.Top+FMenuButton.Height+1)*FCanvasScale);
   w := Bitmap.Width-(VolatileScrollBarSize+1)-x;
-  aw := DoScaleX(FPaletteAlphaWidth, OriginalDPI);
-  h := DoScaleY(FPaletteItemHeight, OriginalDPI);
+  aw := DoScaleX(round(FPaletteAlphaWidth*FCanvasScale), OriginalDPI);
+  h := DoScaleY(round(FPaletteItemHeight*FCanvasScale), OriginalDPI);
   if h < 3 then h := 3;
   availHeight := Bitmap.Height - 2 - y - 1;
   nbVisible := availHeight div (h-1);

+ 13 - 8
lazpaint/uvolatilescrollbar.pas

@@ -8,10 +8,15 @@ interface
 uses
   Classes, SysUtils, Forms, BGRABitmap, BGRAGradients;
 
+const
+  OrigVolatileScrollBarSize = 14;
+  OrigVolatileThumbSize = 24;
+  OrigVolatileBorderSize = 3;
+
 var
-  VolatileScrollBarSize : integer = 14;
-  VolatileThumbSize : integer = 24;
-  VolatileBorderSize : integer = 3;
+  VolatileScrollBarSize : integer = OrigVolatileScrollBarSize;
+  VolatileThumbSize : integer = OrigVolatileThumbSize;
+  VolatileBorderSize : integer = OrigVolatileBorderSize;
 
 type
   TScrollBarKind = Forms.TScrollBarKind;
@@ -42,7 +47,7 @@ type
   public
     constructor Create(X,Y,AWidth,AHeight: integer; ADirection: TScrollBarKind; APosition, AMinimum, AMaximum: integer);
     destructor Destroy; override;
-    class procedure InitDPI;
+    class procedure InitDPI(ACanvasScaleFactor: single);
     function MouseDown(X,Y: integer): boolean;
     function MouseMove(X,Y: integer): boolean;
     function MouseUp({%H-}X,{%H-}Y: integer): boolean;
@@ -208,13 +213,13 @@ begin
   FPhong.DrawRectangle(ADest,lThumb,VolatileBorderSize,h,ColorToBGRA(ColorToRGB(clBtnFace)),true,[]);
 end;
 
-class procedure TVolatileScrollBar.InitDPI;
+class procedure TVolatileScrollBar.InitDPI(ACanvasScaleFactor: single);
 begin
   if not FInitDPI then
   begin
-    VolatileScrollBarSize := ScaleX(VolatileScrollBarSize, OriginalDPI);
-    VolatileThumbSize := ScaleX(VolatileThumbSize, OriginalDPI);
-    VolatileBorderSize := ScaleX(VolatileBorderSize, OriginalDPI);
+    VolatileScrollBarSize := ScaleX(round(VolatileScrollBarSize * ACanvasScaleFactor), OriginalDPI);
+    VolatileThumbSize := ScaleX(round(VolatileThumbSize * ACanvasScaleFactor), OriginalDPI);
+    VolatileBorderSize := ScaleX(round(VolatileBorderSize * ACanvasScaleFactor), OriginalDPI);
     FInitDPI := true;
   end;
 end;

+ 11 - 3
lazpaintcontrols/lcscaledpi.pas

@@ -9,7 +9,8 @@ uses
   Forms, Graphics, Controls, ComCtrls;
 
 procedure ScaleForms(FromDPI: Integer);
-procedure ScaleControl(Control: TControl; FromDPI: Integer; ToDPI_X: Integer = 0; ToDPI_Y: Integer = 0);
+procedure ScaleControl(Control: TControl; FromDPI: Integer;
+  ToDPI_X: Integer = 0; ToDPI_Y: Integer = 0; ScaleToolbar: boolean = false);
 procedure ScaleImageList(SourceList: TImageList; newWidth, newHeight: Integer; TargetList: TImageList);
 function DoScaleX(Size: Integer; FromDPI: Integer; ToDPI: Integer = 0): integer;
 function DoScaleY(Size: Integer; FromDPI: Integer; ToDPI: Integer = 0): integer;
@@ -36,6 +37,9 @@ var
   i: Integer;
 
 begin
+  if (TargetList = SourceList) and (newWidth = SourceList.Width) and
+    (newHeight = SourceList.Height) then exit;
+
   setlength(TempBGRA, SourceList.Count);
   TempBmp := TBitmap.Create;
   for i := 0 to SourceList.Count-1 do
@@ -101,7 +105,8 @@ begin
     Result := Size * ToDPI / FromDPI;
 end;
 
-procedure ScaleControl(Control: TControl; FromDPI: Integer; ToDPI_X: Integer; ToDPI_Y: integer);
+procedure ScaleControl(Control: TControl; FromDPI: Integer; ToDPI_X: Integer; ToDPI_Y: integer;
+  ScaleToolbar: boolean = false);
 var
   n: Integer;
   WinControl: TWinControl;
@@ -126,11 +131,13 @@ begin
   end;
 
   if Control is TToolBar then begin
+    if not ScaleToolbar then exit;
     ToolBarControl:=TToolBar(Control);
     with ToolBarControl do begin
       ButtonWidth:=DoScaleX(ButtonWidth,FromDPI,ToDPI_X);
       ButtonHeight:=DoScaleY(ButtonHeight,FromDPI,ToDPI_Y);
     end;
+    exit;
   end;
 
   if Control is TWinControl then begin
@@ -145,7 +152,8 @@ begin
     if WinControl.ControlCount > 0 then begin
       for n:=0 to WinControl.ControlCount-1 do begin
         if WinControl.Controls[n] is TControl then begin
-          ScaleControl(WinControl.Controls[n],FromDPI,ToDPI_X,ToDPI_Y);
+          ScaleControl(WinControl.Controls[n],FromDPI,ToDPI_X,ToDPI_Y,
+            ScaleToolbar);
         end;
       end;
     end;