diff --git a/MatterControlLib/ApplicationView/Application.cs b/MatterControlLib/ApplicationView/Application.cs index d44d17da6..0df1757a8 100644 --- a/MatterControlLib/ApplicationView/Application.cs +++ b/MatterControlLib/ApplicationView/Application.cs @@ -588,6 +588,12 @@ namespace MatterHackers.MatterControl keyEvent.Handled = true; break; + case 'z': + case 'Z': + view3D.ZoomToSelection(); + keyEvent.Handled = true; + break; + case ' ': view3D.Scene.ClearSelection(); keyEvent.Handled = true; diff --git a/MatterControlLib/PartPreviewWindow/View3D/GridOptionsPanel.cs b/MatterControlLib/PartPreviewWindow/View3D/GridOptionsPanel.cs index 02fff1393..99edb6a80 100644 --- a/MatterControlLib/PartPreviewWindow/View3D/GridOptionsPanel.cs +++ b/MatterControlLib/PartPreviewWindow/View3D/GridOptionsPanel.cs @@ -57,6 +57,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow HAnchor = HAnchor.Center }); this.VAnchor = VAnchor.Fit; + // make sure the button is square this.Width = this.Height; UserSettings.Instance.SettingChanged += UserSettings_SettingChanged; @@ -100,7 +101,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow private GuiWidget ShowGridOptions(ThemeConfig theme) { - popupMenu = new PopupMenu(ApplicationController.Instance.MenuTheme); + popupMenu = new PopupMenu(ApplicationController.Instance.MenuTheme) + { + HAnchor = HAnchor.Absolute, + Width = 80 + }; var siblingList = new List(); diff --git a/MatterControlLib/PartPreviewWindow/View3D/View3DWidget.cs b/MatterControlLib/PartPreviewWindow/View3D/View3DWidget.cs index 8d777e242..61fcbb698 100644 --- a/MatterControlLib/PartPreviewWindow/View3D/View3DWidget.cs +++ b/MatterControlLib/PartPreviewWindow/View3D/View3DWidget.cs @@ -469,85 +469,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow this.Scene.SelectionChanged += SetZoomEnabled; this.Closed += (s, e) => this.Scene.SelectionChanged -= SetZoomEnabled; - AddRoundButton(zoomToSelectionButton, RotatedMargin(zoomToSelectionButton, MathHelper.Tau * .4)).Click += (s, e) => - { - bool NeedsToBeSmaller(RectangleDouble partScreenBounds, RectangleDouble goalBounds) - { - if (partScreenBounds.Bottom < goalBounds.Bottom - || partScreenBounds.Top > goalBounds.Top - || partScreenBounds.Left < goalBounds.Left - || partScreenBounds.Right > goalBounds.Right) - { - return true; - } - - return false; - } - - var selectedItem = this.Scene.SelectedItem; - if (selectedItem != null) - { - var aabb = selectedItem.GetAxisAlignedBoundingBox(); - var center = aabb.Center; - // pan to the center - var world = sceneContext.World; - var screenCenter = new Vector2(world.Width / 2 - selectedObjectPanel.Width / 2, world.Height / 2); - var centerRay = world.GetRayForLocalBounds(screenCenter); - - // make the target size a portion of the total size - var goalBounds = new RectangleDouble(0, 0, world.Width, world.Height); - goalBounds.Inflate(-world.Width * .1); - - int rescaleAttempts = 0; - var testWorld = new WorldView(world.Width, world.Height); - testWorld.RotationMatrix = world.RotationMatrix; - var distance = 80.0; - - void AjustDistance() - { - testWorld.TranslationMatrix = world.TranslationMatrix; - var delta = centerRay.origin + centerRay.directionNormal * distance - center; - testWorld.Translate(delta); - } - - AjustDistance(); - - while (rescaleAttempts++ < 500) - { - - var partScreenBounds = testWorld.GetScreenBounds(aabb); - - if (NeedsToBeSmaller(partScreenBounds, goalBounds)) - { - distance++; - AjustDistance(); - partScreenBounds = testWorld.GetScreenBounds(aabb); - - // If it crossed over the goal reduct the amount we are adjusting by. - if (!NeedsToBeSmaller(partScreenBounds, goalBounds)) - { - break; - } - } - else - { - distance--; - AjustDistance(); - partScreenBounds = testWorld.GetScreenBounds(aabb); - - // If it crossed over the goal reduct the amount we are adjusting by. - if (NeedsToBeSmaller(partScreenBounds, goalBounds)) - { - break; - } - } - } - - TrackballTumbleWidget.AnimateTranslation(center, centerRay.origin + centerRay.directionNormal * distance); - // zoom to fill the view - // viewControls3D.NotifyResetView(); - } - }; + AddRoundButton(zoomToSelectionButton, RotatedMargin(zoomToSelectionButton, MathHelper.Tau * .4)).Click += (s, e) => ZoomToSelection(); var turnTableButton = new RadioIconButton(StaticData.Instance.LoadIcon("spin.png", 16, 16).SetToColor(theme.TextColor), theme) { @@ -700,6 +622,86 @@ namespace MatterHackers.MatterControl.PartPreviewWindow #endif } + public void ZoomToSelection() + { + bool NeedsToBeSmaller(RectangleDouble partScreenBounds, RectangleDouble goalBounds) + { + if (partScreenBounds.Bottom < goalBounds.Bottom + || partScreenBounds.Top > goalBounds.Top + || partScreenBounds.Left < goalBounds.Left + || partScreenBounds.Right > goalBounds.Right) + { + return true; + } + + return false; + } + + var selectedItem = this.Scene.SelectedItem; + if (selectedItem != null) + { + var aabb = selectedItem.GetAxisAlignedBoundingBox(); + var center = aabb.Center; + // pan to the center + var world = sceneContext.World; + var screenCenter = new Vector2(world.Width / 2 - selectedObjectPanel.Width / 2, world.Height / 2); + var centerRay = world.GetRayForLocalBounds(screenCenter); + + // make the target size a portion of the total size + var goalBounds = new RectangleDouble(0, 0, world.Width, world.Height); + goalBounds.Inflate(-world.Width * .1); + + int rescaleAttempts = 0; + var testWorld = new WorldView(world.Width, world.Height); + testWorld.RotationMatrix = world.RotationMatrix; + var distance = 80.0; + + void AjustDistance() + { + testWorld.TranslationMatrix = world.TranslationMatrix; + var delta = centerRay.origin + centerRay.directionNormal * distance - center; + testWorld.Translate(delta); + } + + AjustDistance(); + + while (rescaleAttempts++ < 500) + { + + var partScreenBounds = testWorld.GetScreenBounds(aabb); + + if (NeedsToBeSmaller(partScreenBounds, goalBounds)) + { + distance++; + AjustDistance(); + partScreenBounds = testWorld.GetScreenBounds(aabb); + + // If it crossed over the goal reduct the amount we are adjusting by. + if (!NeedsToBeSmaller(partScreenBounds, goalBounds)) + { + break; + } + } + else + { + distance--; + AjustDistance(); + partScreenBounds = testWorld.GetScreenBounds(aabb); + + // If it crossed over the goal reduct the amount we are adjusting by. + if (NeedsToBeSmaller(partScreenBounds, goalBounds)) + { + break; + } + } + } + + TrackballTumbleWidget.AnimateTranslation(center, centerRay.origin + centerRay.directionNormal * distance); + // zoom to fill the view + // viewControls3D.NotifyResetView(); + } + } + public void UpdateControlButtons(ViewControls3DButtons activeTransformState) { switch (activeTransformState) diff --git a/MatterControlLib/PartPreviewWindow/ViewControls3D.cs b/MatterControlLib/PartPreviewWindow/ViewControls3D.cs index 9261639d8..a41bdcbcc 100644 --- a/MatterControlLib/PartPreviewWindow/ViewControls3D.cs +++ b/MatterControlLib/PartPreviewWindow/ViewControls3D.cs @@ -354,7 +354,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow UpdateToolbarButtons(null, null); } - internal void NotifyResetView() + public void NotifyResetView() { this.ResetView.Invoke(this, null); } diff --git a/MatterControlLib/SetupWizard/HelpTreePanel.cs b/MatterControlLib/SetupWizard/HelpTreePanel.cs index ac9f2f275..90874138e 100644 --- a/MatterControlLib/SetupWizard/HelpTreePanel.cs +++ b/MatterControlLib/SetupWizard/HelpTreePanel.cs @@ -160,6 +160,7 @@ namespace MatterHackers.MatterControl ("shift + ← → ↑ ↓","Pan".Localize()), //("f","Zoom to fit".Localize()), ("w","Zoom to window".Localize()), + ("z","Zoom to selection".Localize()), ("ctrl + s","Save".Localize()), ("ctrl + z","Undo".Localize()), ("ctrl + y","Redo".Localize()),