View Issue Details

IDProjectCategoryView StatusLast Update
0001144Double CommanderViewerpublic2020-06-19 21:52
Reporternicker Assigned ToAlexx2000  
PrioritynormalSeverityfeatureReproducibilityN/A
Status closedResolutionfixed 
ProjectionnoneETAnone 
Product Version0.7.0 (trunk) 
Target Version0.7.0Fixed in Version0.7.0 
Summary0001144: Add option in the viewer to center images
DescriptionIn addition when working with WLX plugins
TagsNo tags attached.
Attached Files
Viewer.patch (15,235 bytes)   
Index: fviewer.lfm
===================================================================
--- fviewer.lfm	(revision 6394)
+++ fviewer.lfm	(working copy)
@@ -2406,6 +2406,14 @@
         Caption = 'Stretch'
         OnClick = miStretchClick
       end
+      object miStretchOnlyLarge: TMenuItem
+        Caption = 'Stretch only large'
+        OnClick = miStretchOnlyLargeClick
+      end
+      object miCenter: TMenuItem
+        Caption = 'Center'
+        OnClick = miCenterClick
+      end
       object miRotate: TMenuItem
         Caption = 'Rotate'
         object mi90: TMenuItem
Index: fviewer.lrt
===================================================================
--- fviewer.lrt	(revision 6394)
+++ fviewer.lrt	(working copy)
@@ -57,6 +57,8 @@
 TFRMVIEWER.MIENCODING.CAPTION=En&coding
 TFRMVIEWER.MIIMAGE.CAPTION=&Image
 TFRMVIEWER.MISTRETCH.CAPTION=Stretch
+TFRMVIEWER.MISTRETCHONLYLARGE.CAPTION=Stretch only large
+TFRMVIEWER.MICENTER.CAPTION=Center
 TFRMVIEWER.MIROTATE.CAPTION=Rotate
 TFRMVIEWER.MI90.CAPTION=+ 90
 TFRMVIEWER.MI180.CAPTION=+ 180
Index: fviewer.pas
===================================================================
--- fviewer.pas	(revision 6394)
+++ fviewer.pas	(working copy)
@@ -146,6 +146,8 @@
     miExit: TMenuItem;
     miImage: TMenuItem;
     miStretch: TMenuItem;
+    miStretchOnlyLarge: TMenuItem;
+    miCenter: TMenuItem;
     miText: TMenuItem;
     miBin: TMenuItem;
     miHex: TMenuItem;
@@ -216,6 +218,8 @@
       Shift: TShiftState);
     procedure miExitClick(Sender: TObject);
     procedure miStretchClick(Sender: TObject);
+    procedure miStretchOnlyLargeClick(Sender: TObject);
+    procedure miCenterClick(Sender: TObject);
     procedure miTextClick(Sender: TObject);
     procedure miAbout2Click(Sender: TObject);
     procedure miSearchClick(Sender: TObject);
@@ -226,6 +230,8 @@
     procedure miChangeEncodingClick(Sender:TObject);
     procedure ViewerPositionChanged(Sender:TObject);
     procedure miRotateClick(Sender: TObject);
+    function  PluginShowFlags : Integer;
+    procedure UpdateImagePlacement;
 
   private
     FileList: TStringList;
@@ -436,8 +442,6 @@
 end;
 
 procedure TfrmViewer.LoadNextFile(const aFileName: String);
-var
-  ShowFlags: Integer;
 begin
   if bPlugin then
     with WlxPlugins.GetWlxModule(ActivePlugin) do
@@ -444,8 +448,7 @@
     begin
       if FileParamVSDetectStr(aFileName, False) then
       begin
-        ShowFlags:= IfThen(miStretch.Checked, lcp_fittowindow, 0);
-        if CallListLoadNext(Self.Handle, aFileName, ShowFlags) <> LISTPLUGIN_ERROR then
+        if CallListLoadNext(Self.Handle, aFileName, PluginShowFlags) <> LISTPLUGIN_ERROR then
           Exit;
       end;
     end;
@@ -878,10 +881,6 @@
   btnReload.Visible:=not(miFullScreen.Checked);
   Status.Visible:=not(miFullScreen.Checked);
   gboxSlideShow.Visible:=miFullScreen.Checked;
-
-  Image.Stretch:= miFullScreen.Checked;
-  Image.AutoSize:= not Image.Stretch;
-  Image.Proportional:= Image.Stretch;
   AdjustImageSize;
   ShowOnTop;
 end;
@@ -1012,14 +1011,18 @@
   EndY:=0;
 end;
 
+function TfrmViewer.PluginShowFlags : Integer;
+begin
+  Result:= IfThen(miStretch.Checked, lcp_fittowindow, 0) or
+           IfThen(miCenter.Checked, lcp_center, 0) or
+           IfThen(miStretchOnlyLarge.Checked, lcp_fitlargeronly, 0)
+end;
+
 function TfrmViewer.CheckPlugins(const sFileName: String; bForce: Boolean = False): Boolean;
 var
   I: Integer;
-  ShowFlags: Integer;
   WlxModule: TWlxModule;
 begin
-  ShowFlags:= IfThen(bForce, lcp_forceshow, 0);
-  ShowFlags:= ShowFlags or IfThen(miStretch.Checked, lcp_fittowindow, 0);
   // DCDebug('WlXPlugins.Count = ' + IntToStr(WlxPlugins.Count));
   for I:= 0 to WlxPlugins.Count - 1 do
   if WlxPlugins.GetWlxModule(I).FileParamVSDetectStr(sFileName, bForce) then
@@ -1028,7 +1031,7 @@
     if not WlxPlugins.LoadModule(I) then Continue;
     WlxModule:= WlxPlugins.GetWlxModule(I);
     DCDebug('WlxModule.Name = ', WlxModule.Name);
-    if WlxModule.CallListLoad(Self.Handle, sFileName, ShowFlags) = 0 then
+    if WlxModule.CallListLoad(Self.Handle, sFileName, IfThen(bForce, lcp_forceshow, 0) or PluginShowFlags) = 0 then
     begin
       WlxModule.UnloadModule;
       Continue;
@@ -1147,9 +1150,6 @@
 procedure TfrmViewer.miZoomClick(Sender: TObject);
 begin
   miStretch.Checked := false;
-  Image.Stretch:=true;
-  Image.Proportional:=true;
-  Image.AutoSize := false;
   if (sender=miZoomIn) or (sender=btnZoomIn)
   then
     begin
@@ -1299,6 +1299,8 @@
 begin
   CloseAction:=caFree;
   gImageStretch:= miStretch.Checked;
+  gImageStretchOnlyLarge:= miStretchOnlyLarge.Checked;
+  gImageCenter:= miCenter.Checked;
   gPreviewVisible := miPreview.Checked;
   gImagePaintMode := ComboBoxPaint.text;
   gImagePaintWidth := StrToInt(ComboBoxWidth.Text) ;
@@ -1353,32 +1355,40 @@
   Close;
 end;
 
-procedure TfrmViewer.miStretchClick(Sender: TObject);
-var
-  ShowFlags: Integer;
+procedure TfrmViewer.UpdateImagePlacement;
 begin
-  miStretch.Checked:= not miStretch.Checked;
   if bImage then
   begin
-    Image.Stretch:= miStretch.Checked;
-    Image.AutoSize:= not Image.Stretch;
-    Image.Proportional:= Image.Stretch;
-    if gboxHightlight.Visible then UndoTmp;
-    if miStretch.Checked then
-      begin
-        gboxPaint.Visible:=false;
-        gboxHightlight.Visible:=false;
-        gboxView.Visible:=true;
-      end;
+    if gboxHightlight.Visible then 
+    begin
+      gboxPaint.Visible:=false;
+      gboxHightlight.Visible:=false;
+      gboxView.Visible:=true;
+      UndoTmp;
+    end;
     AdjustImageSize;
   end
   else if bPlugin then
-  begin
-    ShowFlags:= IfThen(miStretch.Checked, lcp_fittowindow, 0);
-    WlxPlugins.GetWLxModule(ActivePlugin).CallListSendCommand(lc_newparams, ShowFlags)
-  end;
+    WlxPlugins.GetWLxModule(ActivePlugin).CallListSendCommand(lc_newparams , PluginShowFlags)
 end;
 
+procedure TfrmViewer.miStretchClick(Sender: TObject);
+begin
+  miStretch.Checked:= not miStretch.Checked;
+  UpdateImagePlacement;
+end;
+procedure TfrmViewer.miCenterClick(Sender: TObject);
+begin
+   miCenter.Checked:= not miCenter.Checked;
+   UpdateImagePlacement;
+end;
+
+procedure TfrmViewer.miStretchOnlyLargeClick(Sender: TObject);
+begin
+  miStretchOnlyLarge.Checked:= not miStretchOnlyLarge.Checked;
+  UpdateImagePlacement;
+end;
+
 procedure TfrmViewer.miTextClick(Sender: TObject);
 begin
   ExitPluginMode;
@@ -1447,14 +1457,16 @@
   
   sboxImage.DoubleBuffered := True;
   miStretch.Checked := gImageStretch;
+  miStretchOnlyLarge.Checked := gImageStretchOnlyLarge;
+  miCenter.Checked := gImageCenter;
   miPreview.Checked := gPreviewVisible;
   ComboBoxPaint.Text := gImagePaintMode;
   ComboBoxWidth.Text := IntToStr(gImagePaintWidth);
   ColorBoxPaint.Selected := gImagePaintColor;
 
-  Image.Stretch:= miStretch.Checked;
-  Image.AutoSize:= not Image.Stretch;
-  Image.Proportional:= Image.Stretch;
+  Image.Stretch:= True;
+  Image.AutoSize:= False;
+  Image.Proportional:= False;
   Image.SetBounds(0, 0, sboxImage.ClientWidth, sboxImage.ClientHeight);
 
   FThumbSize := gThumbSize;
@@ -1723,67 +1735,43 @@
 // Adjust Image size (width and height) to sboxImage size
 procedure TfrmViewer.AdjustImageSize;
 const
-  fmtImageInfo = '%s (%s %%)';
+  fmtImageInfo = '%dx%d (%.0f %%)';
 var
-  sResolution: String;
-  iScale: Integer = 0;
+  dScaleFactor : Double = 1.0;
+  var iLeft,iTop,iWidth,iHeight : integer;
 begin
-  if miStretch.Checked then
-     begin
-       Image.Stretch:= True;
-       Image.AutoSize:= True;
-       Image.Center:= True;
-       if (Image.Picture.Width > sboxImage.ClientWidth) or (Image.Picture.Height > sboxImage.ClientHeight) then
-         begin
-           Image.AutoSize := False;
-           Image.SetBounds(0, 0, sboxImage.ClientWidth, sboxImage.ClientHeight);
-           sboxImage.HorzScrollBar.Visible:= False;
-           sboxImage.VertScrollBar.Visible:= False;
-           // show image resolution and scale
-           if Image.Picture.Width < Image.Width then
-             begin
-             iScale:= 100*(Image.Picture.Width * Image.ClientHeight) div (Image.Picture.Width* Image.Picture.Height);
-             sResolution:= IntToStr(Image.Picture.Width) + 'x' + IntToStr(Image.Height);
-             end;
-           if Image.Picture.Height < Image.Height then
-             begin
-              iScale:= 100*(Image.ClientWidth * Image.Picture.Height) div (Image.Picture.Width* Image.Picture.Height);
-              sResolution:= IntToStr(Image.Width) + 'x' + IntToStr(Image.Picture.Height);
-             end;
-           if (Image.Picture.Width >= Image.Width) and  (Image.Picture.Height >= Image.Height) then
-             begin
-              iScale:= 100*(Image.Width * Image.Height) div (Image.Picture.Width* Image.Picture.Height);
-              sResolution:= IntToStr(Image.Width) + 'x' + IntToStr(Image.Height);
-             end;
-           Status.Panels[sbpCurrentResolution].Text:= Format(fmtImageInfo, [sResolution, IntToStr(iScale)]);
-           sResolution:= IntToStr(Image.Picture.Width) + 'x' + IntToStr(Image.Picture.Height);
-           Status.Panels[sbpFullResolution].Text:= Format(fmtImageInfo, [sResolution, '100']);
-         end
-       else
-         begin
-           Image.Left:= (sboxImage.ClientWidth-Image.Picture.Width) div 2;        //move image to center
-           Image.Top:=  (sboxImage.ClientHeight-Image.Picture.Height) div 2;
-           sResolution:= IntToStr(Image.Picture.Width) + 'x' + IntToStr(Image.Picture.Height);
-           Status.Panels[sbpCurrentResolution].Text:= Format(fmtImageInfo, [sResolution, '100']);
-           Status.Panels[sbpFullResolution].Text:= Status.Panels[2].Text;
-         end;
-     end
+  // Place and resize image
+  if (miStretch.Checked) then
+  begin
+    dScaleFactor:= Min(sboxImage.ClientWidth / Image.Picture.Width ,sboxImage.ClientHeight / Image.Picture.Height);
+    dScaleFactor:= IfThen((miStretchOnlyLarge.Checked) and (dScaleFactor > 1.0), 1.0, dScaleFactor);
+  end;
+
+  iWidth:= trunc(Image.Picture.Width * dScaleFactor);
+  iHeight:= trunc(Image.Picture.Height * dScaleFactor);
+  if (miCenter.Checked) then
+  begin
+    iLeft:= (sboxImage.ClientWidth - iWidth) div 2;
+    iTop:= (sboxImage.ClientHeight - iHeight) div 2;
+  end
   else
-    begin
-      // show image resolution and scale
-      Image.Left:= 0;
-      Image.Top:= 0;
-      Image.Stretch:= False;
-      Image.AutoSize:= True;
-      sboxImage.HorzScrollBar.Visible:= Image.Width > sboxImage.ClientWidth;
-      sboxImage.VertScrollBar.Visible:= Image.Height > sboxImage.ClientHeight;
-      if (Image.Picture.Width <> 0) and (Image.Picture.Height <> 0) then
-        iScale:= 100 * (Image.Width * Image.Height) div (Image.Picture.Width * Image.Picture.Height);
-      sResolution:= IntToStr(Image.Width) + 'x' + IntToStr(Image.Height);
-      Status.Panels[sbpCurrentResolution].Text:= Format(fmtImageInfo, [sResolution, IntToStr(iScale)]);
-      sResolution:= IntToStr(Image.Picture.Width) + 'x' + IntToStr(Image.Picture.Height);
-      Status.Panels[sbpFullResolution].Text:= Format(fmtImageInfo, [sResolution, '100']);
-    end;
+  begin
+    iLeft:= 0;
+    iTop:= 0;
+  end;
+  Image.SetBounds(Max(iLeft,0), Max(iTop,0), iWidth , iHeight);
+
+  // Update scrollbars
+  //TODO: fix - calculations are correct but it seems like scroll bars
+  // are being updated only after a second call to Form.Resize
+  if (iLeft < 0) then
+    sboxImage.HorzScrollBar.Position:= -iLeft;
+  if (iTop < 0) then
+    sboxImage.VertScrollBar.Position:= -iTop;
+
+  // Update status bar
+  Status.Panels[sbpCurrentResolution].Text:= Format(fmtImageInfo, [iWidth,iHeight,  100.0 * dScaleFactor]);
+  Status.Panels[sbpFullResolution].Text:= Format(fmtImageInfo, [Image.Picture.Width,Image.Picture.Height, 100.0]);
 end;
 
 // Try to rotate image
@@ -2170,18 +2158,15 @@
 
 procedure TfrmViewer.cm_LoadNextFile(const Params: array of string);
 var
-  I, ShowFlags: Integer;
+  I : Integer;
 begin
   I:= iActiveFile + 1;
   if I >= FileList.Count then
     I:= 0;
 
-  if bPlugin then
-    begin
-      ShowFlags:= IfThen(miStretch.Checked, lcp_fittowindow, 0);
-      if WlxPlugins.GetWlxModule(ActivePlugin).CallListLoadNext(Self.Handle, FileList[I], ShowFlags) <> LISTPLUGIN_ERROR then
-        Exit;
-    end;
+  if (bPlugin)
+    And (WlxPlugins.GetWlxModule(ActivePlugin).CallListLoadNext(Self.Handle, FileList[I], PluginShowFlags) <> LISTPLUGIN_ERROR) then
+      Exit;
   ExitPluginMode;
   if pnlPreview.Visible then
     begin
@@ -2198,18 +2183,15 @@
 
 procedure TfrmViewer.cm_LoadPrevFile(const Params: array of string);
 var
-  I, ShowFlags: Integer;
+  I: Integer;
 begin
   I:= iActiveFile - 1;
   if I < 0 then
     I:= FileList.Count - 1;
+  if (bPlugin)
+      And (WlxPlugins.GetWlxModule(ActivePlugin).CallListLoadNext(Self.Handle, FileList[I], PluginShowFlags) <> LISTPLUGIN_ERROR) then
+        Exit;
 
-  if bPlugin then
-    begin
-      ShowFlags:= IfThen(miStretch.Checked, lcp_fittowindow, 0);
-      if WlxPlugins.GetWlxModule(ActivePlugin).CallListLoadNext(Self.Handle, FileList[I], ShowFlags) <> LISTPLUGIN_ERROR then
-        Exit;
-    end;
   if pnlPreview.Visible then
     begin
       if DrawPreview.Col = 0  then
Index: uglobs.pas
===================================================================
--- uglobs.pas	(revision 6394)
+++ uglobs.pas	(working copy)
@@ -403,6 +403,8 @@
   {Viewer}
   gPreviewVisible,
   gImageStretch: Boolean;
+  gImageStretchOnlyLarge: Boolean;
+  gImageCenter: Boolean;
   gCopyMovePath1,
   gCopyMovePath2,
   gCopyMovePath3,
@@ -1343,6 +1345,8 @@
 
   {Viewer}
   gImageStretch := False;
+  gImageStretchOnlyLarge := False;
+  gImageCenter := True;
   gPreviewVisible := False;
   gCopyMovePath1 := '';
   gCopyMovePath2 := '';
@@ -1904,6 +1908,8 @@
   gCutTextToColWidth := gIni.ReadBool('Configuration', 'CutTextToColWidth', True);
 
   gImageStretch:=  gIni.ReadBool('Viewer', 'Image.Stretch', False);
+  gImageStretchOnlyLarge:=  gIni.ReadBool('Viewer', 'Image.StretchLargeOnly', False);
+  gImageCenter:=  gIni.ReadBool('Viewer', 'Image.Center', True);
 
   { Operations options }
   gOperationOptionSymLinks := TFileSourceOperationOptionSymLink(
@@ -2423,6 +2429,8 @@
     if Assigned(Node) then
     begin
       gImageStretch := GetValue(Node, 'ImageStretch', gImageStretch);
+      gImageStretchOnlyLarge := GetValue(Node, 'ImageStretchLargeOnly', gImageStretchOnlyLarge);
+      gImageCenter := GetValue(Node, 'ImageCenter', gImageCenter);
       gPreviewVisible := GetValue(Node, 'PreviewVisible', gPreviewVisible);
       gCopyMovePath1 := GetValue(Node, 'CopyMovePath1', gCopyMovePath1);
       gCopyMovePath2 := GetValue(Node, 'CopyMovePath2', gCopyMovePath2);
@@ -2810,6 +2818,8 @@
     Node := FindNode(Root, 'Viewer',True);
     SetValue(Node, 'PreviewVisible',gPreviewVisible);
     SetValue(Node, 'ImageStretch',gImageStretch);
+    SetValue(Node, 'ImageStretchLargeOnly',gImageStretchOnlyLarge);
+    SetValue(Node, 'ImageCenter',gImageCenter);
     SetValue(Node, 'CopyMovePath1', gCopyMovePath1);
     SetValue(Node, 'CopyMovePath2', gCopyMovePath2);
     SetValue(Node, 'CopyMovePath3', gCopyMovePath3);
Viewer.patch (15,235 bytes)   
Fixed in Revision6484
Operating system
Widgetset
Architecture

Activities

nicker

2015-11-23 02:38

reporter   ~0001601

I've upload a patch 'Viewer.patch' with the following modifications:

1. Adds support to center an image for internal viewer and for external plug-in.
2. separates the dependency between centering an image and stretching ( fitting to window) for internal viewer and for external plug-in
2. Adds support to fit to window only large images for internal viewer and for external plug-in.
3. Simplifies and shortens image placement logic for the internal viewer.
4. serialization for the new features.

nicker

2016-01-17 03:45

reporter   ~0001633

Lines 397 and 398 of the patch are not included in the changset.

397+ gImageStretchOnlyLarge:= gIni.ReadBool('Viewer', 'Image.StretchLargeOnly', False);
398+ gImageCenter:= gIni.ReadBool('Viewer', 'Image.Center', True);

Alexx2000

2016-01-17 13:18

administrator   ~0001634

Yes, because it useless. Loading from .ini for backward compatibility. Old version does not have these options so there are nothing to load.

Issue History

Date Modified Username Field Change
2015-08-09 20:36 nicker New Issue
2015-11-23 02:36 nicker File Added: Viewer.patch
2015-11-23 02:38 nicker Note Added: 0001601
2015-12-08 00:00 Alexx2000 Status new => acknowledged
2015-12-08 00:00 Alexx2000 Target Version => 0.7.0
2016-01-16 22:59 Alexx2000 Fixed in Revision => 6484
2016-01-16 22:59 Alexx2000 Status acknowledged => resolved
2016-01-16 22:59 Alexx2000 Fixed in Version => 0.7.0
2016-01-16 22:59 Alexx2000 Resolution open => fixed
2016-01-16 22:59 Alexx2000 Assigned To => Alexx2000
2016-01-17 03:45 nicker Note Added: 0001633
2016-01-17 13:18 Alexx2000 Note Added: 0001634
2020-06-19 21:52 Alexx2000 Status resolved => closed