public void Initialize(Cockpit cockpit) { cockpit.Name = "modelCockpit"; // Configure how the cockpit moves cockpit.PositionMode = Cockpit.MovementMode.TrackPosition; // [RMS] use orientation mode to make cockpit follow view orientation. // (however default widgets below are off-screen!) //cockpit.PositionMode = Cockpit.MovementMode.TrackOrientation; FScene Scene = cockpit.Scene; BoxContainer screenContainer = new BoxContainer(new Cockpit2DContainerProvider(cockpit)); PinnedBoxes2DLayoutSolver screenLayout = new PinnedBoxes2DLayoutSolver(screenContainer); PinnedBoxesLayout layout = new PinnedBoxesLayout(cockpit, screenLayout) { StandardDepth = 1.5f }; cockpit.AddLayout(layout, "2D", true); Func <string, float, HUDLabel> MakeButtonF = (label, buttonW) => { HUDLabel button = new HUDLabel() { Shape = OrthogenUI.MakeMenuButtonRect(buttonW, OrthogenUI.MenuButtonHeight), TextHeight = OrthogenUI.MenuButtonTextHeight, AlignmentHorz = HorizontalAlignment.Center, BackgroundColor = OrthogenUI.ButtonBGColor, TextColor = OrthogenUI.ButtonTextColor, DisabledTextColor = OrthogenUI.DisabledButtonTextColor, Text = label, EnableBorder = true, BorderWidth = OrthogenUI.StandardButtonBorderWidth, BorderColor = OrthogenUI.ButtonTextColor }; button.Create(); button.Name = label; button.Enabled = true; return(button); }; Func <string, float, float, HUDSpacer> MakeSpacerF = (label, spacerw, spacerh) => { HUDSpacer spacer = new HUDSpacer() { Shape = new HUDShape(HUDShapeType.Rectangle, spacerw, spacerh) }; spacer.Create(); spacer.Name = label; return(spacer); }; HUDElementList button_list = new HUDElementList() { Width = OrthogenUI.MenuButtonWidth, Height = 5 * OrthogenUI.MenuButtonHeight, Spacing = 10 * OrthogenUI.PixelScale, Direction = HUDElementList.ListDirection.Vertical }; HUDLabel trim_scan_button = MakeButtonF("Trim Scan", OrthogenUI.MenuButtonWidth); trim_scan_button.OnClicked += (sender, e) => { OG.Transition(OGWorkflow.TrimScanStartT); }; button_list.AddListItem(trim_scan_button); HUDLabel align_scan_button = MakeButtonF("Align Scan", OrthogenUI.MenuButtonWidth); align_scan_button.OnClicked += (sender, e) => { OG.Transition(OGWorkflow.AlignScanStartT); }; button_list.AddListItem(align_scan_button); HUDLabel accept_scan_button = MakeButtonF("Done Scan", OrthogenUI.MenuButtonWidth); accept_scan_button.OnClicked += (sender, e) => { OG.TransitionToState(RectifyState.Identifier); }; button_list.AddListItem(accept_scan_button); button_list.AddListItem(MakeSpacerF("space", OrthogenUI.MenuButtonWidth, 0.5f * OrthogenUI.MenuButtonHeight)); HUDLabel draw_offset_area_button = MakeButtonF("Offset Area", OrthogenUI.MenuButtonWidth); draw_offset_area_button.OnClicked += (sender, e) => { OGActions.CurrentLegDeformType = LegModel.LegDeformationTypes.Offset; OG.Transition(OGWorkflow.DrawAreaStartT); }; button_list.AddListItem(draw_offset_area_button); HUDLabel draw_smooth_area_button = MakeButtonF("Smooth Area", OrthogenUI.MenuButtonWidth); draw_smooth_area_button.OnClicked += (sender, e) => { OGActions.CurrentLegDeformType = LegModel.LegDeformationTypes.Smooth; OG.Transition(OGWorkflow.DrawAreaStartT); }; button_list.AddListItem(draw_smooth_area_button); HUDLabel add_plane_button = MakeButtonF("Add Plane", OrthogenUI.MenuButtonWidth); add_plane_button.OnClicked += (sender, e) => { OG.Transition(OGWorkflow.AddDeformRingStartT); }; button_list.AddListItem(add_plane_button); HUDLabel add_lengthen_button = MakeButtonF("Add Lengthen", OrthogenUI.MenuButtonWidth); add_lengthen_button.OnClicked += (sender, e) => { if (OGActions.CanAddLengthenOp()) { OGActions.AddLengthenOp(); } }; button_list.AddListItem(add_lengthen_button); HUDLabel sculpt_curve_button = MakeButtonF("Sculpt Curve", OrthogenUI.MenuButtonWidth); WorkflowRouter sculpt_router = WorkflowRouter.Build(new[] { OGWorkflow.RectifyState, OGWorkflow.SculptAreaStartT, OGWorkflow.SocketState, OGWorkflow.SculptTrimlineStartT }); sculpt_curve_button.OnClicked += (sender, e) => { sculpt_router.Apply(OG.Model.Workflow); }; button_list.AddListItem(sculpt_curve_button); HUDLabel accept_rectify_button = MakeButtonF("Begin Socket", OrthogenUI.MenuButtonWidth); accept_rectify_button.OnClicked += (sender, e) => { OG.Leg.SetOpWidgetVisibility(false); OG.TransitionToState(SocketDesignState.Identifier); }; button_list.AddListItem(accept_rectify_button); button_list.AddListItem(MakeSpacerF("space", OrthogenUI.MenuButtonWidth, 0.5f * OrthogenUI.MenuButtonHeight)); HUDLabel draw_trim_line_button = MakeButtonF("Draw Trimline", OrthogenUI.MenuButtonWidth); draw_trim_line_button.OnClicked += (sender, e) => { OG.Transition(OGWorkflow.DrawTrimlineStartT); }; button_list.AddListItem(draw_trim_line_button); HUDLabel plane_trim_line_button = MakeButtonF("Plane Trimline", OrthogenUI.MenuButtonWidth); plane_trim_line_button.OnClicked += (sender, e) => { OG.Transition(OGWorkflow.PlaneTrimlineStartT); }; button_list.AddListItem(plane_trim_line_button); HUDLabel add_socket_button = MakeButtonF("Add Socket", OrthogenUI.MenuButtonWidth); add_socket_button.OnClicked += (sender, e) => { if (OGActions.CanAddSocket()) { OGActions.AddSocket(); } }; button_list.AddListItem(add_socket_button); HUDLabel export_socket_button = MakeButtonF("Export", OrthogenUI.MenuButtonWidth); export_socket_button.OnClicked += (sender, e) => { if (OGActions.CanExportSocket()) { OGActions.ExportSocket(); } }; button_list.AddListItem(export_socket_button); button_list.AddListItem(MakeSpacerF("space", OrthogenUI.MenuButtonWidth, 1.0f * OrthogenUI.MenuButtonHeight)); HUDLabel accept_button = MakeButtonF("Accept", OrthogenUI.MenuButtonWidth); accept_button.OnClicked += (sender, e) => { OGActions.AcceptCurrentTool(); }; HUDLabel cancel_button = MakeButtonF("Cancel", OrthogenUI.MenuButtonWidth); cancel_button.OnClicked += (sender, e) => { OGActions.CancelCurrentTool(); }; button_list.AddListItem(accept_button); button_list.AddListItem(cancel_button); button_list.Create(); button_list.Name = "button_bar"; // align button list to center of timeline layout.Add(button_list, new LayoutOptions() { Flags = LayoutFlags.None, PinSourcePoint2D = LayoutUtil.BoxPointF(button_list, BoxPosition.TopLeft), PinTargetPoint2D = LayoutUtil.BoxPointF(screenContainer, BoxPosition.TopLeft, 10 * OrthogenUI.PixelScale * (Vector2f.AxisX - Vector2f.AxisY)) }); screenLayout.RecomputeLayout(); // Configure interaction behaviors // - below we add behaviors for mouse, gamepad, and spatial devices (oculus touch, etc) // - keep in mind that Tool objects will register their own behaviors when active // setup key handlers (need to move to behavior...) cockpit.AddKeyHandler(new OrthoGenKeyHandler(cockpit.Context)); // these behaviors let us interact with UIElements (ie left-click/trigger, or either triggers for Touch) cockpit.InputBehaviors.Add(new Mouse2DCockpitUIBehavior(cockpit.Context) { Priority = 0 }); cockpit.InputBehaviors.Add(new VRMouseUIBehavior(cockpit.Context) { Priority = 1 }); // selection / multi-selection behaviors // Note: this custom behavior implements some selection redirects that we use in various parts of Archform cockpit.InputBehaviors.Add(new MouseMultiSelectBehavior(cockpit.Context) { Priority = 10 }); // left click-drag to tumble, and left click-release to de-select cockpit.InputBehaviors.Add(new MouseClickDragSuperBehavior() { Priority = 100, DragBehavior = new MouseViewRotateBehavior(cockpit.Context) { Priority = 100, RotateSpeed = 3.0f }, ClickBehavior = new MouseDeselectBehavior(cockpit.Context) { Priority = 999 } }); // also right-click-drag to tumble cockpit.InputBehaviors.Add(new MouseViewRotateBehavior(cockpit.Context) { Priority = 100, RotateSpeed = 3.0f, ActivateF = MouseBehaviors.RightButtonPressedF, ContinueF = MouseBehaviors.RightButtonDownF }); // middle-click-drag to pan cockpit.InputBehaviors.Add(new MouseViewPanBehavior(cockpit.Context) { Priority = 100, PanSpeed = 10.0f, ActivateF = MouseBehaviors.MiddleButtonPressedF, ContinueF = MouseBehaviors.MiddleButtonDownF }); cockpit.OverrideBehaviors.Add(new MouseWheelZoomBehavior(cockpit) { Priority = 100, ZoomScale = 100.0f }); // touch input cockpit.InputBehaviors.Add(new TouchUIBehavior(cockpit.Context) { Priority = 1 }); cockpit.InputBehaviors.Add(new Touch2DCockpitUIBehavior(cockpit.Context) { Priority = 0 }); cockpit.InputBehaviors.Add(new TouchViewManipBehavior(cockpit.Context) { Priority = 999, TouchZoomSpeed = 1.0f, TouchPanSpeed = 0.3f }); // update buttons enable/disable on state transitions, selection changes Action updateStateChangeButtons = () => { trim_scan_button.Enabled = OG.CanTransition(OGWorkflow.TrimScanStartT); align_scan_button.Enabled = OG.CanTransition(OGWorkflow.AlignScanStartT); accept_scan_button.Enabled = OG.IsInState(ScanState.Identifier) && OG.CanTransitionToState(RectifyState.Identifier); draw_offset_area_button.Enabled = OG.CanTransition(OGWorkflow.DrawAreaStartT); draw_smooth_area_button.Enabled = OG.CanTransition(OGWorkflow.DrawAreaStartT); add_plane_button.Enabled = OG.CanTransition(OGWorkflow.AddDeformRingStartT); add_lengthen_button.Enabled = OGActions.CanAddLengthenOp(); accept_rectify_button.Enabled = OG.IsInState(RectifyState.Identifier) && OG.CanTransitionToState(SocketDesignState.Identifier); draw_trim_line_button.Enabled = OG.CanTransition(OGWorkflow.DrawTrimlineStartT); plane_trim_line_button.Enabled = OG.CanTransition(OGWorkflow.PlaneTrimlineStartT); add_socket_button.Enabled = OGActions.CanAddSocket(); export_socket_button.Enabled = OGActions.CanExportSocket(); sculpt_curve_button.Enabled = sculpt_router.CanApply(OG.Model.Workflow); }; OG.OnWorfklowInitialized += (o, e) => { updateStateChangeButtons(); }; OG.OnStateTransition += (from, to) => { updateStateChangeButtons(); }; OG.OnDataModelModified += (from, to) => { updateStateChangeButtons(); }; cockpit.Scene.SelectionChangedEvent += (o, e) => { if (OG.WorkflowInitialized) { updateStateChangeButtons(); } }; cockpit.Scene.ChangedEvent += (scene, so, type) => { if (OG.WorkflowInitialized) { updateStateChangeButtons(); } }; // accept/cancel buttons need to be checked every frame because the CanApply state // could change at any time, and there is no event about it cockpit.Context.RegisterEveryFrameAction("update_buttons", () => { if (cockpit.Context.ToolManager.ActiveRightTool != null) { cancel_button.Enabled = true; accept_button.Enabled = cockpit.Context.ToolManager.ActiveRightTool.CanApply; } else { cancel_button.Enabled = accept_button.Enabled = false; } // [RMS] currently this state changes outside workflow state changes... add_socket_button.Enabled = OGActions.CanAddSocket(); }); }
public void Initialize(Cockpit cockpit) { cockpit.Name = "sampleCockpit"; // Configure how the cockpit moves cockpit.PositionMode = Cockpit.MovementMode.TrackPosition; // initialize layout BoxContainer screenContainer = new BoxContainer(new Cockpit2DContainerProvider(cockpit)); PinnedBoxes2DLayoutSolver screenLayout = new PinnedBoxes2DLayoutSolver(screenContainer); PinnedBoxesLayout layout = new PinnedBoxesLayout(cockpit, screenLayout) { StandardDepth = 1.0f }; cockpit.AddLayout(layout, "2D", true); float pixelScale = cockpit.GetPixelScale(); float buttonDiam = 150 * pixelScale; HUDElementList primitives_list = new HUDElementList() { Width = 5 * buttonDiam, Height = buttonDiam, Spacing = 25 * pixelScale, Direction = HUDElementList.ListDirection.Horizontal }; // Add some UI elements to the cockpit // - cylinder & box buttons - double-click or drag/drop into scene // - button to start and cancel draw-primitives tool Color bgColor = new Color(0.7f, 0.7f, 1.0f, 0.7f); Material bgMaterial = (bgColor.a == 1.0f) ? MaterialUtil.CreateStandardMaterial(bgColor) : MaterialUtil.CreateTransparentMaterial(bgColor); Material primMaterial = MaterialUtil.CreateStandardMaterial(Color.yellow); DropPrimitiveButton cylinderButton = create_primitive_button(cockpit, "create_cylinder", buttonDiam / 2, PrimitiveType.Cylinder, SOTypes.Cylinder, 0.7f, bgMaterial, primMaterial, () => { return(new CylinderSO().Create(cockpit.Scene.DefaultSOMaterial)); }); primitives_list.AddListItem(cylinderButton); DropPrimitiveButton boxButton = create_primitive_button(cockpit, "create_box", buttonDiam / 2, PrimitiveType.Cube, SOTypes.Box, 0.8f, bgMaterial, primMaterial, () => { return(new BoxSO().Create(cockpit.Scene.DefaultSOMaterial)); }); primitives_list.AddListItem(boxButton); primitives_list.Create(); primitives_list.Name = "button_bar"; // align primitives_list to bottom-left layout.Add(primitives_list, new LayoutOptions() { Flags = LayoutFlags.None, PinSourcePoint2D = LayoutUtil.BoxPointF(primitives_list, BoxPosition.BottomLeft), PinTargetPoint2D = LayoutUtil.BoxPointF(screenContainer, BoxPosition.BottomLeft, 25 * pixelScale * Vector2f.One) }); //float fToolsX = 35.0f; //float fToolButtonRadius = 0.08f; // buttons for draw-primitive tool and cancel-tool button //ActivateToolButton drawPrimButton = add_tool_button(cockpit, DrawPrimitivesTool.Identifier, fHUDRadius, // fToolsX - fButtonsSpacing, fButtonsY, fToolButtonRadius, bgMaterial, primMaterial, // new toolInfo() { identifier = DrawPrimitivesTool.Identifier, sMeshPath = "draw_primitive", fMeshScaleFudge = 1.2f }); //cockpit.AddUIElement(drawPrimButton); //ActivateToolButton cancelButton = add_tool_button(cockpit, "cancel", fHUDRadius, // fToolsX, fButtonsY, fToolButtonRadius, bgMaterial, primMaterial, // new toolInfo() { identifier = "cancel", sMeshPath = "cancel", fMeshScaleFudge = 1.2f }); //cockpit.AddUIElement(cancelButton); // Configure interaction behaviors // - below we add behaviors for mouse, gamepad, and spatial devices (oculus touch, etc) // - keep in mind that Tool objects will register their own behaviors when active // setup key handlers (need to move to behavior...) cockpit.AddKeyHandler(new BasicShapesDemo_KeyHandler(cockpit.Context)); // these behaviors let us interact with UIElements (ie left-click/trigger, or either triggers for Touch) cockpit.InputBehaviors.Add(new Mouse2DCockpitUIBehavior(cockpit.Context) { Priority = 0 }); cockpit.InputBehaviors.Add(new VRMouseUIBehavior(cockpit.Context) { Priority = 1 }); // selection / multi-selection behaviors cockpit.InputBehaviors.Add(new MouseMultiSelectBehavior(cockpit.Context) { Priority = 10 }); cockpit.InputBehaviors.Add(new GamepadMultiSelectBehavior(cockpit.Context) { Priority = 10 }); // left click-drag to tumble, and left click-release to de-select cockpit.InputBehaviors.Add(new MouseClickDragSuperBehavior() { Priority = 100, DragBehavior = new MouseViewRotateBehavior(cockpit.Context) { Priority = 100, RotateSpeed = 3.0f }, ClickBehavior = new MouseDeselectBehavior(cockpit.Context) { Priority = 999 } }); // also right-click-drag to tumble cockpit.InputBehaviors.Add(new MouseViewRotateBehavior(cockpit.Context) { Priority = 100, RotateSpeed = 3.0f, ActivateF = MouseBehaviors.RightButtonPressedF, ContinueF = MouseBehaviors.RightButtonDownF }); // middle-click-drag to pan cockpit.InputBehaviors.Add(new MouseViewPanBehavior(cockpit.Context) { Priority = 100, PanSpeed = 1.0f, ActivateF = MouseBehaviors.MiddleButtonPressedF, ContinueF = MouseBehaviors.MiddleButtonDownF }); cockpit.OverrideBehaviors.Add(new MouseWheelZoomBehavior(cockpit) { Priority = 100, ZoomScale = 10.0f }); // touch input cockpit.InputBehaviors.Add(new TouchUIBehavior(cockpit.Context) { Priority = 1 }); cockpit.InputBehaviors.Add(new Touch2DCockpitUIBehavior(cockpit.Context) { Priority = 0 }); cockpit.InputBehaviors.Add(new TouchViewManipBehavior(cockpit.Context) { Priority = 999, TouchZoomSpeed = 0.1f, TouchPanSpeed = 0.03f }); }
public void Initialize(Cockpit cockpit) { cockpit.Name = "modelCockpit"; // Configure how the cockpit moves //cockpit.PositionMode = Cockpit.MovementMode.TrackPosition; // [RMS] use orientation mode to make cockpit follow view orientation. // (however default widgets below are off-screen!) cockpit.PositionMode = Cockpit.MovementMode.TrackOrientation; BoxContainer screenContainer = new BoxContainer(new Cockpit2DContainerProvider(cockpit)); PinnedBoxes2DLayoutSolver screenLayout = new PinnedBoxes2DLayoutSolver(screenContainer); PinnedBoxesLayout layout = new PinnedBoxesLayout(cockpit, screenLayout) { StandardDepth = 2.0f }; cockpit.AddLayout(layout, "2D", true); Func <string, float, HUDLabel> MakeButtonF = (label, buttonW) => { HUDLabel button = new HUDLabel() { Shape = CotangentUI.MakeMenuButtonRect(buttonW, CotangentUI.MenuButtonHeight), TextHeight = CotangentUI.MenuButtonTextHeight, AlignmentHorz = HorizontalAlignment.Center, BackgroundColor = CotangentUI.ButtonBGColor, TextColor = CotangentUI.ButtonTextColor, Text = label, EnableBorder = true, BorderWidth = CotangentUI.StandardButtonBorderWidth, BorderColor = CotangentUI.ButtonTextColor }; button.Create(); button.Name = label; button.Enabled = true; return(button); }; Vector2f progressOffsetY = 4 * CotangentUI.PixelScale * Vector2f.AxisY; HUDRadialProgress slicerProgress = new HUDRadialProgress() { Radius = 18 * CotangentUI.PixelScale }; slicerProgress.Create(); slicerProgress.Name = "slicer_progress"; int MAX_PROGRESS = 1000; slicerProgress.MaxProgress = MAX_PROGRESS; CC.SlicingProgressEvent += (status) => { if (status.bFailed) { double t = 0.5 * (double)status.curProgress / (double)status.maxProgress; slicerProgress.Progress = (int)(t * MAX_PROGRESS); slicerProgress.CompletedColor = Colorf.VideoRed; } else { double t = 0.5 * (double)status.curProgress / (double)status.maxProgress; slicerProgress.Progress = (int)(t * MAX_PROGRESS); slicerProgress.CompletedColor = Colorf.BlueMetal; } }; CC.ToolpathProgressEvent += (status) => { if (status.bFailed) { double t = 0.5 + 0.5 * (double)status.curProgress / (double)status.maxProgress; slicerProgress.Progress = (int)(t * MAX_PROGRESS); slicerProgress.CompletedColor = Colorf.VideoRed; } else { double t = 0.5 + 0.5 * (double)status.curProgress / (double)status.maxProgress; if (status.curProgress == 0 && status.maxProgress == 1) { t = 0; } slicerProgress.Progress = (int)(t * MAX_PROGRESS); slicerProgress.CompletedColor = (status.curProgress == status.maxProgress) ? Colorf.LightGreen : Colorf.BlueMetal; } }; layout.Add(slicerProgress, new LayoutOptions() { Flags = LayoutFlags.None, PinSourcePoint2D = LayoutUtil.BoxPointF(slicerProgress, BoxPosition.CenterBottom), PinTargetPoint2D = LayoutUtil.BoxPointF(screenContainer, BoxPosition.CenterBottom, progressOffsetY) }); HUDButton progressClick = new HUDButton() { Shape = new HUDShape(HUDShapeType.Disc, slicerProgress.Radius) }; fMaterial normalMaterial = MaterialUtil.CreateFlatMaterialF(Colorf.White, 0); fMaterial pauseMaterial = MaterialUtil.CreateTransparentImageMaterialF("icons/progress_pause"); fMaterial pausedMaterial = MaterialUtil.CreateTransparentImageMaterialF("icons/progress_play"); if (CCPreferences.ActiveSlicingUpdateMode == CCPreferences.SlicingUpdateModes.ImmediateSlicing) { progressClick.Create(normalMaterial, null, pauseMaterial); } else { progressClick.Create(pausedMaterial, null, null); } progressClick.Name = "progress_click"; layout.Add(progressClick, new LayoutOptions() { Flags = LayoutFlags.None, DepthShift = -0.1f, PinSourcePoint2D = LayoutUtil.BoxPointF(progressClick, BoxPosition.CenterBottom), PinTargetPoint2D = LayoutUtil.BoxPointF(screenContainer, BoxPosition.CenterBottom, progressOffsetY) }); progressClick.OnClicked += (o, e) => { if (CCPreferences.ActiveSlicingUpdateMode == CCPreferences.SlicingUpdateModes.ImmediateSlicing) { CCPreferences.ActiveSlicingUpdateMode = CCPreferences.SlicingUpdateModes.SliceOnDemand; progressClick.StandardMaterial = pausedMaterial; progressClick.HoverMaterial = null; } else { CCPreferences.ActiveSlicingUpdateMode = CCPreferences.SlicingUpdateModes.ImmediateSlicing; progressClick.StandardMaterial = normalMaterial; progressClick.HoverMaterial = pauseMaterial; } if (CC.Toolpather.ToolpathsValid == false) { // not sure why we have to invalidate slicing here, but if we don't toolpath // computation will not stop when we pause... CC.Slicer.InvalidateSlicing(); //CC.InvalidateToolPaths(); } }; CotangentUI.PrintViewHUDItems = new List <HUDStandardItem>() { slicerProgress, progressClick }; screenLayout.RecomputeLayout(); // Configure interaction behaviors // - below we add behaviors for mouse, gamepad, and spatial devices (oculus touch, etc) // - keep in mind that Tool objects will register their own behaviors when active // setup key handlers (need to move to behavior...) cockpit.AddKeyHandler(new CotangentKeyHandler(cockpit.Context)); // these behaviors let us interact with UIElements (ie left-click/trigger, or either triggers for Touch) cockpit.InputBehaviors.Add(new Mouse2DCockpitUIBehavior(cockpit.Context) { Priority = 0 }); cockpit.InputBehaviors.Add(new VRMouseUIBehavior(cockpit.Context) { Priority = 1 }); // selection / multi-selection behaviors // Note: this custom behavior implements some selection redirects that we use in various parts of Archform cockpit.InputBehaviors.Add(new MouseMultiSelectBehavior(cockpit.Context) { Priority = 10 }); // left click-drag to tumble, and left click-release to de-select cockpit.InputBehaviors.Add(new MouseClickDragSuperBehavior() { Priority = 100, DragBehavior = new MouseViewRotateBehavior(cockpit.Context) { Priority = 100, RotateSpeed = 3.0f }, ClickBehavior = new MouseDeselectBehavior(cockpit.Context) { Priority = 999 } }); // also right-click-drag to tumble cockpit.InputBehaviors.Add(new MouseViewRotateBehavior(cockpit.Context) { Priority = 100, RotateSpeed = 3.0f, ActivateF = MouseBehaviors.RightButtonPressedF, ContinueF = MouseBehaviors.RightButtonDownF }); // middle-click-drag to pan cockpit.InputBehaviors.Add(new MouseViewPanBehavior(cockpit.Context) { Priority = 100, PanSpeed = 0.01f, Adaptive = true, ActivateF = MouseBehaviors.MiddleButtonPressedF, ContinueF = MouseBehaviors.MiddleButtonDownF }); cockpit.OverrideBehaviors.Add(new MouseWheelZoomBehavior(cockpit) { Priority = 100, ZoomScale = 0.2f, Adaptive = true }); // touch input cockpit.InputBehaviors.Add(new TouchUIBehavior(cockpit.Context) { Priority = 1 }); cockpit.InputBehaviors.Add(new Touch2DCockpitUIBehavior(cockpit.Context) { Priority = 0 }); cockpit.InputBehaviors.Add(new TouchViewManipBehavior(cockpit.Context) { Priority = 999, TouchZoomSpeed = 0.1f, TouchPanSpeed = 0.03f }); }