Skip to content

Commit

Permalink
Fixes [Bug #592534] Zoom shifts viewport. Viewport isn't preserved if…
Browse files Browse the repository at this point in the history
… zoom is selected from drop down menu.
  • Loading branch information
khairuddinniam authored and jpobst committed Dec 28, 2010
1 parent 2a20973 commit a472d27
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 73 deletions.
32 changes: 19 additions & 13 deletions Pinta.Core/Actions/ViewActions.cs
Expand Up @@ -46,6 +46,7 @@ public class ViewActions
public Gtk.Action Fullscreen { get; private set; }

public ToolBarComboBox ZoomComboBox { get; private set; }
public string[] ZoomCollection { get; private set; }

public ViewActions ()
{
Expand All @@ -71,8 +72,9 @@ public ViewActions ()
Inches = new Gtk.RadioAction ("Inches", Catalog.GetString ("Inches"), null, null, 1);
Centimeters = new Gtk.RadioAction ("Centimeters", Catalog.GetString ("Centimeters"), null, null, 2);
Fullscreen = new Gtk.Action ("Fullscreen", Catalog.GetString ("Fullscreen"), null, Stock.Fullscreen);

ZoomComboBox = new ToolBarComboBox (75, 11, true, "3600%", "2400%", "1600%", "1200%", "800%", "700%", "600%", "500%", "400%", "300%", "200%", "100%", "66%", "50%", "33%", "25%", "16%", "12%", "8%", "5%", "Window");

ZoomCollection = new string[] { "3600%", "2400%", "1600%", "1200%", "800%", "700%", "600%", "500%", "400%", "300%", "200%", "100%", "66%", "50%", "33%", "25%", "16%", "12%", "8%", "5%", "Window" };
ZoomComboBox = new ToolBarComboBox (75, 11, true, ZoomCollection);

// Make sure these are the same group so only one will be selected at a time
Inches.Group = Pixels.Group;
Expand Down Expand Up @@ -184,18 +186,9 @@ public void ResumeZoomUpdate ()
{
suspend_zoom_change = false;
}

#region Action Handlers
private void HandlePintaCoreActionsViewActualSizeActivated (object sender, EventArgs e)
{
PintaCore.Actions.View.ZoomComboBox.ComboBox.Active = 11;
}

private void HandlePintaCoreActionsViewZoomComboBoxComboBoxChanged (object sender, EventArgs e)
public void UpdateCanvasScale ()
{
if (suspend_zoom_change)
return;

string text = PintaCore.Actions.View.ZoomComboBox.ComboBox.ActiveText;

if (text == Catalog.GetString ("Window")) {
Expand All @@ -214,7 +207,20 @@ private void HandlePintaCoreActionsViewZoomComboBoxComboBoxChanged (object sende
percent = percent / 100.0;

PintaCore.Workspace.Scale = percent;

}

#region Action Handlers
private void HandlePintaCoreActionsViewActualSizeActivated (object sender, EventArgs e)
{
PintaCore.Actions.View.ZoomComboBox.ComboBox.Active = 11;
}

private void HandlePintaCoreActionsViewZoomComboBoxComboBoxChanged (object sender, EventArgs e)
{
if (suspend_zoom_change)
return;

PintaCore.Workspace.ActiveDocument.Workspace.ZoomManually ();
}

private void HandlePintaCoreActionsViewZoomOutActivated (object sender, EventArgs e)
Expand Down
140 changes: 80 additions & 60 deletions Pinta.Core/Classes/DocumentWorkspace.cs
@@ -1,4 +1,4 @@
//
//
// DocumentWorkspace.cs
//
// Author:
Expand Down Expand Up @@ -34,10 +34,12 @@ public class DocumentWorkspace
{
private Document document;
private Size canvas_size;
private enum ZoomType {
private enum ZoomType
{
ZoomIn,
ZoomOut
};
ZoomOut,
ZoomManually
}

internal DocumentWorkspace (Document document)
{
Expand All @@ -49,13 +51,13 @@ internal DocumentWorkspace (Document document)
public bool CanvasFitsInWindow {
get {
Gtk.Viewport view = (Gtk.Viewport)PintaCore.Chrome.DrawingArea.Parent;

int window_x = view.Allocation.Width;
int window_y = view.Children[0].Allocation.Height;

if (CanvasSize.Width <= window_x && CanvasSize.Height <= window_y)
return true;

return false;
}
}
Expand All @@ -71,34 +73,34 @@ internal DocumentWorkspace (Document document)
}

public DocumentWorkspaceHistory History { get; private set; }

public bool ImageFitsInWindow {
get {
Gtk.Viewport view = (Gtk.Viewport)PintaCore.Chrome.DrawingArea.Parent;

int window_x = view.Allocation.Width;
int window_y = view.Children[0].Allocation.Height;

if (document.ImageSize.Width <= window_x && document.ImageSize.Height <= window_y)
return true;

return false;
}
}

public Cairo.PointD Offset {
get { return new Cairo.PointD ((PintaCore.Chrome.DrawingArea.Allocation.Width - canvas_size.Width) / 2, (PintaCore.Chrome.DrawingArea.Allocation.Height - canvas_size.Height) / 2); }
}

public double Scale {
get { return (double)CanvasSize.Width / (double)document.ImageSize.Width; }
set {
if (value != (double)CanvasSize.Width / (double)document.ImageSize.Width || value != (double)CanvasSize.Height / (double)document.ImageSize.Height) {
int new_x = (int)(document.ImageSize.Width * value);
int new_y = (int)((new_x * document.ImageSize.Height) / document.ImageSize.Width);

CanvasSize = new Gdk.Size (new_x, new_y);
Invalidate();
Invalidate ();
}
}
}
Expand All @@ -110,7 +112,7 @@ public void Invalidate ()
{
PintaCore.Workspace.OnCanvasInvalidated (new CanvasInvalidatedEventArgs ());
}

public void Invalidate (Gdk.Rectangle rect)
{
rect = new Gdk.Rectangle ((int)((rect.X) * Scale + Offset.X), (int)((rect.Y) * Scale + Offset.Y), (int)(rect.Width * Scale), (int)(rect.Height * Scale));
Expand All @@ -121,25 +123,25 @@ public bool PointInCanvas (Cairo.PointD point)
{
if (point.X < 0 || point.Y < 0)
return false;

if (point.X >= document.ImageSize.Width || point.Y >= document.ImageSize.Height)
return false;

return true;
}

public void RecenterView (double x, double y)
{
Gtk.Viewport view = (Gtk.Viewport)PintaCore.Chrome.DrawingArea.Parent;

view.Hadjustment.Value = Utility.Clamp (x * Scale - view.Hadjustment.PageSize / 2, view.Hadjustment.Lower, view.Hadjustment.Upper);
view.Vadjustment.Value = Utility.Clamp (y * Scale - view.Vadjustment.PageSize / 2, view.Vadjustment.Lower, view.Vadjustment.Upper);
}

public void ScrollCanvas (int dx, int dy)
{
Gtk.Viewport view = (Gtk.Viewport)PintaCore.Chrome.DrawingArea.Parent;

view.Hadjustment.Value = Utility.Clamp (dx + view.Hadjustment.Value, view.Hadjustment.Lower, view.Hadjustment.Upper - view.Hadjustment.PageSize);
view.Vadjustment.Value = Utility.Clamp (dy + view.Vadjustment.Value, view.Vadjustment.Lower, view.Vadjustment.Upper - view.Vadjustment.PageSize);
}
Expand All @@ -156,7 +158,7 @@ public void ZoomIn ()

public void ZoomOut ()
{
ZoomAndRecenterView (ZoomType.ZoomOut, new Cairo.PointD (-1 , -1)); // Zoom out relative to the center of the viewport.
ZoomAndRecenterView (ZoomType.ZoomOut, new Cairo.PointD (-1, -1)); // Zoom out relative to the center of the viewport.
}

public void ZoomInFromMouseScroll (Cairo.PointD point)
Expand All @@ -169,15 +171,20 @@ public void ZoomOutFromMouseScroll (Cairo.PointD point)
ZoomAndRecenterView (ZoomType.ZoomOut, point); // Zoom out relative to mouse position.
}

public void ZoomManually ()
{
ZoomAndRecenterView (ZoomType.ZoomManually, new Cairo.PointD (-1, -1));
}

public void ZoomToRectangle (Cairo.Rectangle rect)
{
double ratio;

if (document.ImageSize.Width / rect.Width <= document.ImageSize.Height / rect.Height)
ratio = document.ImageSize.Width / rect.Width;
else
ratio = document.ImageSize.Height / rect.Height;

(PintaCore.Actions.View.ZoomComboBox.ComboBox as Gtk.ComboBoxEntry).Entry.Text = String.Format ("{0:F}%", ratio * 100.0);
Gtk.Main.Iteration (); //Force update of scrollbar upper before recenter
RecenterView (rect.X + rect.Width / 2, rect.Y + rect.Height / 2);
Expand All @@ -188,61 +195,74 @@ public void ZoomToRectangle (Cairo.Rectangle rect)
private void ZoomAndRecenterView (ZoomType zoomType, Cairo.PointD point)
{
double zoom;

if (!double.TryParse (PintaCore.Actions.View.ZoomComboBox.ComboBox.ActiveText.Trim ('%'), out zoom))
zoom = Scale * 100;

zoom = Math.Min (zoom, 3600);

PintaCore.Chrome.DrawingArea.GdkWindow.FreezeUpdates ();

PintaCore.Actions.View.SuspendZoomUpdate ();

Gtk.Viewport view = (Gtk.Viewport)PintaCore.Chrome.DrawingArea.Parent;

bool adjustOnMousePosition = point.X >= 0.0 && point.Y >= 0.0;

double center_x = adjustOnMousePosition ?
point.X : view.Hadjustment.Value + (view.Hadjustment.PageSize / 2.0);
double center_y = adjustOnMousePosition ?
point.Y : view.Vadjustment.Value + (view.Vadjustment.PageSize / 2.0);

center_x = (center_x - Offset.X) / Scale;
center_y = (center_y - Offset.Y) / Scale;

int i = 0;

Predicate<string> UpdateZoomLevel = zoomInList => {
switch (zoomType) {
case ZoomType.ZoomIn:
if (zoomInList == Catalog.GetString ("Window") || int.Parse (zoomInList.Trim ('%')) <= zoom) {
PintaCore.Actions.View.ZoomComboBox.ComboBox.Active = i - 1;
return true;
if (zoomType == ZoomType.ZoomIn || zoomType == ZoomType.ZoomOut) {
int i = 0;

Predicate<string> UpdateZoomLevel = zoomInList =>
{
switch (zoomType) {
case ZoomType.ZoomIn:
if (zoomInList == Catalog.GetString ("Window") || int.Parse (zoomInList.Trim ('%')) <= zoom) {
PintaCore.Actions.View.ZoomComboBox.ComboBox.Active = i - 1;
return true;
}
break;
case ZoomType.ZoomOut:
if (zoomInList == Catalog.GetString ("Window"))
return true;
if (int.Parse (zoomInList.Trim ('%')) < zoom) {
PintaCore.Actions.View.ZoomComboBox.ComboBox.Active = i;
return true;
}
break;
}
break;
case ZoomType.ZoomOut :
if (zoomInList == Catalog.GetString ("Window"))
return true;
if (int.Parse (zoomInList.Trim ('%')) < zoom) {
PintaCore.Actions.View.ZoomComboBox.ComboBox.Active = i;
return true;
}
break;
return false;
};

foreach (string item in PintaCore.Actions.View.ZoomCollection) {
if (UpdateZoomLevel (item))
break;

i++;
}
return false;
};

foreach (object item in (PintaCore.Actions.View.ZoomComboBox.ComboBox.Model as Gtk.ListStore)) {
if (UpdateZoomLevel (((object[])item)[0].ToString ()))
break;

i++;
}

PintaCore.Actions.View.UpdateCanvasScale ();

// Quick fix : need to manually update Upper limit because the value is not changing after updating the canvas scale.
// TODO : I think there is an event need to be fired so that those values updated automatically.
view.Hadjustment.Upper = CanvasSize.Width < view.Hadjustment.PageSize ? view.Hadjustment.PageSize : CanvasSize.Width;
view.Vadjustment.Upper = CanvasSize.Height < view.Vadjustment.PageSize ? view.Vadjustment.PageSize : CanvasSize.Height;

RecenterView (center_x, center_y);

PintaCore.Actions.View.ResumeZoomUpdate ();
PintaCore.Chrome.DrawingArea.GdkWindow.ThawUpdates ();
}
#endregion
Expand Down

0 comments on commit a472d27

Please sign in to comment.