added a hotkey for zoom to selection

This commit is contained in:
Lars Brubaker 2021-05-25 17:25:44 -07:00
parent 9a2c73e1a4
commit 7e9d730df9
5 changed files with 95 additions and 81 deletions

View file

@ -588,6 +588,12 @@ namespace MatterHackers.MatterControl
keyEvent.Handled = true; keyEvent.Handled = true;
break; break;
case 'z':
case 'Z':
view3D.ZoomToSelection();
keyEvent.Handled = true;
break;
case ' ': case ' ':
view3D.Scene.ClearSelection(); view3D.Scene.ClearSelection();
keyEvent.Handled = true; keyEvent.Handled = true;

View file

@ -57,6 +57,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
HAnchor = HAnchor.Center HAnchor = HAnchor.Center
}); });
this.VAnchor = VAnchor.Fit; this.VAnchor = VAnchor.Fit;
// make sure the button is square
this.Width = this.Height; this.Width = this.Height;
UserSettings.Instance.SettingChanged += UserSettings_SettingChanged; UserSettings.Instance.SettingChanged += UserSettings_SettingChanged;
@ -100,7 +101,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private GuiWidget ShowGridOptions(ThemeConfig theme) 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<GuiWidget>(); var siblingList = new List<GuiWidget>();

View file

@ -469,85 +469,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
this.Scene.SelectionChanged += SetZoomEnabled; this.Scene.SelectionChanged += SetZoomEnabled;
this.Closed += (s, e) => this.Scene.SelectionChanged -= SetZoomEnabled; this.Closed += (s, e) => this.Scene.SelectionChanged -= SetZoomEnabled;
AddRoundButton(zoomToSelectionButton, RotatedMargin(zoomToSelectionButton, MathHelper.Tau * .4)).Click += (s, e) => AddRoundButton(zoomToSelectionButton, RotatedMargin(zoomToSelectionButton, MathHelper.Tau * .4)).Click += (s, e) => 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();
}
};
var turnTableButton = new RadioIconButton(StaticData.Instance.LoadIcon("spin.png", 16, 16).SetToColor(theme.TextColor), theme) var turnTableButton = new RadioIconButton(StaticData.Instance.LoadIcon("spin.png", 16, 16).SetToColor(theme.TextColor), theme)
{ {
@ -700,6 +622,86 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
#endif #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) public void UpdateControlButtons(ViewControls3DButtons activeTransformState)
{ {
switch (activeTransformState) switch (activeTransformState)

View file

@ -354,7 +354,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
UpdateToolbarButtons(null, null); UpdateToolbarButtons(null, null);
} }
internal void NotifyResetView() public void NotifyResetView()
{ {
this.ResetView.Invoke(this, null); this.ResetView.Invoke(this, null);
} }

View file

@ -160,6 +160,7 @@ namespace MatterHackers.MatterControl
("shift + ← → ↑ ↓","Pan".Localize()), ("shift + ← → ↑ ↓","Pan".Localize()),
//("f","Zoom to fit".Localize()), //("f","Zoom to fit".Localize()),
("w","Zoom to window".Localize()), ("w","Zoom to window".Localize()),
("z","Zoom to selection".Localize()),
("ctrl + s","Save".Localize()), ("ctrl + s","Save".Localize()),
("ctrl + z","Undo".Localize()), ("ctrl + z","Undo".Localize()),
("ctrl + y","Redo".Localize()), ("ctrl + y","Redo".Localize()),