public static void Paste(this BedConfig sceneContext)
        {
            var scene = sceneContext.Scene;

            if (Clipboard.Instance.ContainsImage)
            {
                // Persist
                string filePath = ApplicationDataStorage.Instance.GetNewLibraryFilePath(".png");
                AggContext.ImageIO.SaveImageData(
                    filePath,
                    Clipboard.Instance.GetImage());

                scene.UndoBuffer.AddAndDo(
                    new InsertCommand(
                        scene,
                        new ImageObject3D()
                {
                    AssetPath = filePath
                }));
            }
            else if (Clipboard.Instance.ContainsText)
            {
                if (Clipboard.Instance.GetText() == "!--IObjectSelection--!")
                {
                    sceneContext.DuplicateItem(pastObjectXOffset, ApplicationController.ClipboardItem);
                    // each time we put in the object offset it a bit more
                    pastObjectXOffset += 5;
                }
            }
        }
Exemple #2
0
        public GCodeLayerDetailsView(GCodeFile gCodeMemoryFile, BedConfig sceneContext, ThemeConfig theme)
            : base(FlowDirection.TopToBottom)
        {
            this.theme = theme;

            GuiWidget layerIndex        = AddSetting("Number".Localize(), "");
            GuiWidget layerTime         = AddSetting("Time".Localize(), "");
            GuiWidget layerTimeToHere   = AddSetting("Time From Start".Localize(), "");
            GuiWidget layerTimeFromHere = AddSetting("Time to End".Localize(), "");
            GuiWidget layerHeight       = AddSetting("Height".Localize(), "");
            GuiWidget layerWidth        = AddSetting("Layer Top".Localize(), "");
            GuiWidget layerFanSpeeds    = AddSetting("Fan Speed".Localize(), "");

            void UpdateLayerDisplay(object sender, EventArgs e)
            {
                layerIndex.Text        = $"{sceneContext.ActiveLayerIndex + 1}";
                layerTime.Text         = gCodeMemoryFile.LayerTime(sceneContext.ActiveLayerIndex);
                layerTimeToHere.Text   = gCodeMemoryFile.LayerTimeToHere(sceneContext.ActiveLayerIndex);
                layerTimeFromHere.Text = gCodeMemoryFile.LayerTimeFromeHere(sceneContext.ActiveLayerIndex);
                layerHeight.Text       = $"{gCodeMemoryFile.GetLayerHeight(sceneContext.ActiveLayerIndex):0.###}";
                layerWidth.Text        = $"{gCodeMemoryFile.GetLayerTop(sceneContext.ActiveLayerIndex):0.###}";
                var fanSpeed = gCodeMemoryFile.GetLayerFanSpeeds(sceneContext.ActiveLayerIndex);

                layerFanSpeeds.Text = string.IsNullOrWhiteSpace(fanSpeed) ? "Unchanged" : fanSpeed;
            }

            sceneContext.ActiveLayerChanged += UpdateLayerDisplay;

            // and do the initial setting
            UpdateLayerDisplay(this, null);
        }
Exemple #3
0
        public GCodePanel(PrinterConfig printer, BedConfig sceneContext, ThemeConfig theme)
            : base(FlowDirection.TopToBottom)
        {
            this.sceneContext = sceneContext;
            this.theme        = theme;
            this.printer      = printer;

            SectionWidget sectionWidget;

            this.AddChild(
                sectionWidget = new SectionWidget(
                    "Options".Localize(),
                    new GCodeOptionsPanel(sceneContext, printer, theme),
                    theme,
                    ApplicationController.Instance.GetViewOptionButtons(sceneContext, printer, theme))
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit,
                Padding = 0
            });

            sectionWidget.ContentPanel.Descendants <SettingsRow>().First().Border = 0;

            var scrollable = new ScrollableWidget(true)
            {
                Name    = "editorPanel",
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch,
            };

            scrollable.ScrollArea.HAnchor = HAnchor.Stretch;

            scrollable.AddChild(loadedGCodeSection = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit
            });

            this.AddChild(scrollable);

            this.RefreshGCodeDetails(printer);

            this.EnsureSectionWidgetStyling(this.Children <SectionWidget>());

            ActiveSliceSettings.SettingChanged.RegisterEvent((s, e) =>
            {
                if (e is StringEventArgs stringEvent)
                {
                    if (stringEvent.Data == "extruder_offset")
                    {
                        printer.Bed.GCodeRenderer?.Clear3DGCode();
                    }
                }
            }, ref unregisterEvents);

            printer.Bed.LoadedGCodeChanged += Bed_LoadedGCodeChanged;
            printer.Bed.RendererOptions.PropertyChanged += RendererOptions_PropertyChanged;
        }
Exemple #4
0
        public SliceLayerSelector(PrinterConfig printer, BedConfig sceneContext)
        {
            var theme = ApplicationController.Instance.Theme;

            this.sceneContext = sceneContext;

            this.AddChild(layerScrollbar = new LayerScrollbar(printer, sceneContext)
            {
                VAnchor = VAnchor.Stretch,
                HAnchor = HAnchor.Right
            });

            layerSlider = layerScrollbar.layerSlider;

            var tagContainer = new HorizontalTag()
            {
                HAnchor  = HAnchor.Fit | HAnchor.Right,
                VAnchor  = VAnchor.Fit,
                Padding  = new BorderDouble(6, 4, 10, 4),
                Margin   = new BorderDouble(right: layerScrollbar.Width + layerScrollbar.Margin.Width),
                TagColor = (theme.Colors.IsDarkTheme) ? theme.Shade : theme.SlightShade
            };

            currentLayerInfo = new InlineEditControl("1000")
            {
                Name             = "currentLayerInfo",
                TextColor        = theme.Colors.PrimaryTextColor,
                GetDisplayString = (value) => $"{value}",
                HAnchor          = HAnchor.Right | HAnchor.Fit,
                VAnchor          = VAnchor.Absolute | VAnchor.Fit,
            };
            currentLayerInfo.EditComplete += (s, e) =>
            {
                layerScrollbar.Value = currentLayerInfo.Value - 1;
            };

            tagContainer.AddChild(currentLayerInfo);
            this.AddChild(tagContainer);

            currentLayerInfo.Visible = true;
            layerInfoHalfHeight      = currentLayerInfo.Height / 2;
            currentLayerInfo.Visible = false;

            layerSlider.ValueChanged += (s, e) =>
            {
                currentLayerInfo.StopEditing();
                currentLayerInfo.Position = new Vector2(0, (double)(layerSlider.Position.Y + layerSlider.PositionPixelsFromFirstValue - layerInfoHalfHeight));
            };

            // Set initial position
            currentLayerInfo.Position = new Vector2(0, (double)(layerSlider.Position.Y + layerSlider.PositionPixelsFromFirstValue - layerInfoHalfHeight));

            sceneContext.ActiveLayerChanged += SetPositionAndValue;
            layerScrollbar.MouseEnter       += SetPositionAndValue;
        }
        public GCodePanel(PrinterConfig printer, BedConfig sceneContext, ThemeConfig theme)
            : base(FlowDirection.TopToBottom)
        {
            this.sceneContext = sceneContext;
            this.theme        = theme;
            this.printer      = printer;

            SectionWidget sectionWidget;

            this.AddChild(
                sectionWidget = new SectionWidget(
                    "Options".Localize(),
                    new GCodeOptionsPanel(sceneContext, printer, theme),
                    theme)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit,
                Padding = 0
            });

            sectionWidget.ContentPanel.Descendants <SettingsRow>().First().Border = 0;

            var scrollable = new ScrollableWidget(true)
            {
                Name    = "editorPanel",
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch,
            };

            scrollable.ScrollArea.HAnchor = HAnchor.Stretch;

            scrollable.AddChild(loadedGCodeSection = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit
            });

            this.AddChild(scrollable);

            this.RefreshGCodeDetails(printer);

            this.EnsureSectionWidgetStyling(this.Children <SectionWidget>());

            var firstSection = this.Children <SectionWidget>().First();

            firstSection.BorderColor = Color.Transparent;             // Disable top border on first item to produce a more flat, dark top edge

            // Register listeners
            printer.Settings.SettingChanged             += Printer_SettingChanged;
            printer.Bed.LoadedGCodeChanged              += Bed_LoadedGCodeChanged;
            printer.Bed.RendererOptions.PropertyChanged += RendererOptions_PropertyChanged;
        }
        public async Task <IHttpActionResult> Post(int id, BedConfigInputModel model)
        {
            BedConfig bedConfig = new BedConfig()
            {
                Id = model.Id,
                VehicleToBedConfigCount = model.VehicleToBedConfigCount
            };
            CommentsStagingModel comment = new CommentsStagingModel()
            {
                Comment = model.Comment,
            };
            var attachments     = SetUpAttachmentsModels(model.Attachments);
            var changeRequestId = await _bedConfigApplicationService.DeleteAsync(bedConfig, id, CurrentUser.Email, comment, attachments);

            return(Ok(changeRequestId));
        }
Exemple #7
0
        public ChromeTab CreatePartTab(string tabTitle, BedConfig sceneContext, ThemeConfig theme)
        {
            var partTab = new ChromeTab(
                tabTitle,
                tabControl,
                new PartTabPage(null, sceneContext, theme, ""),
                theme,
                AggContext.StaticData.LoadIcon("cube.png", 16, 16, theme.InvertIcons))
            {
                Name        = "newPart" + tabControl.AllTabs.Count(),
                MinimumSize = new Vector2(120, theme.TabButtonHeight)
            };

            tabControl.AddTab(partTab);

            return(partTab);
        }
        public async Task <IHttpActionResult> Post(BedConfigInputModel model)
        {
            BedConfig bedConfig = new BedConfig()
            {
                Id          = model.Id,
                BedLengthId = model.BedLengthId,
                BedTypeId   = model.BedTypeId
            };
            CommentsStagingModel comment = new CommentsStagingModel()
            {
                Comment = model.Comment
            };
            var attachments     = SetUpAttachmentsModels(model.Attachments);
            var changeRequestId = await _bedConfigApplicationService.AddAsync(bedConfig, CurrentUser.Email, comment, attachments);

            return(Ok(changeRequestId));
        }
        public MeshViewerWidget(BedConfig sceneContext, InteractionLayer interactionLayer, string startingTextMessage = "", EditorType editorType = EditorType.Part)
        {
            this.EditorMode       = editorType;
            this.scene            = sceneContext.Scene;
            this.sceneContext     = sceneContext;
            this.interactionLayer = interactionLayer;
            this.World            = interactionLayer.World;

            var theme = ApplicationController.Instance.Theme;

            gridColors = new GridColors()
            {
                Gray  = theme.ResolveColor(theme.ActiveTabColor, theme.GetBorderColor((theme.Colors.IsDarkTheme ? 35 : 55))),
                Red   = theme.ResolveColor(theme.ActiveTabColor, new Color(Color.Red, (theme.Colors.IsDarkTheme ? 105 : 170))),
                Green = theme.ResolveColor(theme.ActiveTabColor, new Color(Color.Green, (theme.Colors.IsDarkTheme ? 105 : 170))),
                Blue  = theme.ResolveColor(theme.ActiveTabColor, new Color(Color.Blue, 195))
            };

            gCodeMeshColor = new Color(theme.Colors.PrimaryAccentColor, 35);

            scene.SelectionChanged += (sender, e) =>
            {
                Invalidate();
                lastSelectionChangedMs = UiThread.CurrentTimerMs;
            };

            BedColor         = new ColorF(.8, .8, .8, .7).ToColor();
            BuildVolumeColor = new ColorF(.2, .8, .3, .2).ToColor();

            this.interactionLayer.DrawGlTransparentContent += Draw_GlTransparentContent;

            if (ViewOnlyTexture == null)
            {
                UiThread.RunOnIdle(() =>
                {
                    ViewOnlyTexture = new ImageBuffer(32, 32, 32);
                    var graphics2D  = ViewOnlyTexture.NewGraphics2D();
                    graphics2D.Clear(Color.White);
                    graphics2D.FillRectangle(0, 0, ViewOnlyTexture.Width / 2, ViewOnlyTexture.Height, Color.LightGray);
                    // request the texture so we can set it to repeat
                    var plugin = ImageGlPlugin.GetImageGlPlugin(ViewOnlyTexture, true, true, false);
                });
            }
        }
Exemple #10
0
        public MeshViewerWidget(BedConfig sceneContext, InteractionLayer interactionLayer, ThemeConfig theme, EditorType editorType = EditorType.Part)
        {
            this.EditorMode       = editorType;
            this.scene            = sceneContext.Scene;
            this.sceneContext     = sceneContext;
            this.interactionLayer = interactionLayer;
            this.World            = interactionLayer.World;
            this.theme            = theme;

            gridColors = new GridColors()
            {
                Gray  = theme.ResolveColor(theme.BackgroundColor, theme.GetBorderColor((theme.IsDarkTheme ? 35 : 55))),
                Red   = theme.ResolveColor(theme.BackgroundColor, new Color(Color.Red, (theme.IsDarkTheme ? 105 : 170))),
                Green = theme.ResolveColor(theme.BackgroundColor, new Color(Color.Green, (theme.IsDarkTheme ? 105 : 170))),
                Blue  = theme.ResolveColor(theme.BackgroundColor, new Color(Color.Blue, 195))
            };

            gCodeMeshColor = new Color(theme.PrimaryAccentColor, 35);

            // Register listeners
            scene.SelectionChanged += selection_Changed;

            BuildVolumeColor = new ColorF(.2, .8, .3, .2).ToColor();

            this.interactionLayer.DrawGlTransparentContent += Draw_GlTransparentContent;

            if (ViewOnlyTexture == null)
            {
                // TODO: What is the ViewOnlyTexture???
                UiThread.RunOnIdle(() =>
                {
                    ViewOnlyTexture = new ImageBuffer(32, 32, 32);
                    var graphics2D  = ViewOnlyTexture.NewGraphics2D();
                    graphics2D.Clear(Color.White);
                    graphics2D.FillRectangle(0, 0, ViewOnlyTexture.Width / 2, ViewOnlyTexture.Height, Color.LightGray);
                    // request the texture so we can set it to repeat
                    var plugin = ImageGlPlugin.GetImageGlPlugin(ViewOnlyTexture, true, true, false);
                });
            }
        }
        private async Task UpdateVehicleToBedConfigDocuments(BedConfig updatedBedConfig)
        {
            bool isEndReached = false;
            int  pageNumber   = 1;

            do
            {
                var vehicleToBedConfigSearchResult =
                    await
                    _vehicletoBedConfigSearchService.SearchAsync(null,
                                                                 $"bedConfigId eq {updatedBedConfig.Id}", new SearchOptions()
                {
                    RecordCount = 1000, PageNumber = pageNumber
                });

                var existingVehicleToBedConfigDocuments = vehicleToBedConfigSearchResult.Documents;

                if (existingVehicleToBedConfigDocuments != null && existingVehicleToBedConfigDocuments.Any())
                {
                    foreach (var existingVehicleToBedConfigDocument in existingVehicleToBedConfigDocuments)
                    {
                        existingVehicleToBedConfigDocument.BedConfigChangeRequestId = -1;
                        existingVehicleToBedConfigDocument.BedLengthId     = updatedBedConfig.BedLengthId;
                        existingVehicleToBedConfigDocument.BedLength       = updatedBedConfig.BedLength.Length;
                        existingVehicleToBedConfigDocument.BedLengthMetric = updatedBedConfig.BedLength.BedLengthMetric;
                        existingVehicleToBedConfigDocument.BedTypeId       = updatedBedConfig.BedTypeId;
                        existingVehicleToBedConfigDocument.BedTypeName     = updatedBedConfig.BedType.Name;
                    }

                    await
                    this._vehicleToBedConfigIndexingService.UploadDocumentsAsync(existingVehicleToBedConfigDocuments.ToList());

                    pageNumber++;
                }
                else
                {
                    isEndReached = true;
                }
            } while (!isEndReached);
        }
Exemple #12
0
        /// <summary>
        /// Behavior from removed Edit button - keeping around for reuse as an advanced feature in the future
        /// </summary>
        /// <returns></returns>
        private async Task EditChildInIsolatedContext()
        {
            var bed = new BedConfig();

            var partPreviewContent = this.Parents <PartPreviewContent>().FirstOrDefault();

            partPreviewContent.CreatePartTab(
                "New Part",
                bed,
                theme);

            var clonedItem = this.item.Clone();

            // Edit in Identity transform
            clonedItem.Matrix = Matrix4X4.Identity;

            await bed.LoadContent(
                new EditContext()
            {
                ContentStore = new DynamicContentStore((libraryItem, object3D) =>
                {
                    var replacement = object3D.Clone();

                    this.item.Parent.Children.Modify(list =>
                    {
                        list.Remove(item);

                        // Restore matrix of item being replaced
                        replacement.Matrix = item.Matrix;

                        list.Add(replacement);

                        item = replacement;
                    });

                    sceneContext.Scene.SelectedItem = replacement;
                }),
                SourceItem = new InMemoryLibraryItem(clonedItem),
            });
        }
        public async Task <IHttpActionResult> Replace(int id, BedConfigInputModel model)
        {
            BedConfig bedConfig = new BedConfig()
            {
                Id                  = model.Id,
                BedLengthId         = model.BedLengthId,
                BedTypeId           = model.BedTypeId,
                VehicleToBedConfigs = model.VehicleToBedConfigs.Select(item => new VehicleToBedConfig
                {
                    BedConfigId = item.BedConfigId,
                    Id          = item.Id,
                    VehicleId   = item.VehicleId
                }).ToList(),
            };

            CommentsStagingModel comment = new CommentsStagingModel {
                Comment = model.Comment
            };
            var attachments     = SetUpAttachmentsModels(model.Attachments);
            var changeRequestId = await _bedConfigApplicationService.ReplaceAsync(bedConfig, id, CurrentUser.Email, comment, attachments);

            return(Ok(changeRequestId));
        }
        public static void InsertNewItem(this BedConfig sceneContext, IObject3D newItem)
        {
            var scene = sceneContext.Scene;

            // Reposition first item to bed center
            if (scene.Children.Count == 0)
            {
                var aabb   = newItem.GetAxisAlignedBoundingBox(Matrix4X4.Identity);
                var center = aabb.Center;

                newItem.Matrix *= Matrix4X4.CreateTranslation(
                    (sceneContext.BedCenter.X - center.X),
                    (sceneContext.BedCenter.Y - center.Y),
                    -aabb.minXYZ.Z);
            }

            // Create and perform a new insert operation
            var insertOperation = new InsertCommand(scene, newItem);

            insertOperation.Do();

            // Store the operation for undo/redo
            scene.UndoBuffer.Add(insertOperation);
        }
Exemple #15
0
        public ViewStyleButton(BedConfig sceneContext, ThemeConfig theme)
            : base(theme)
        {
            this.sceneContext = sceneContext;
            this.PopupContent = () => ShowViewOptions(sceneContext, theme);
            this.HAnchor      = HAnchor.Fit;
            this.VAnchor      = VAnchor.Fit;

            viewIcons = new Dictionary <RenderTypes, ImageBuffer>()
            {
                [RenderTypes.Shaded]    = AggContext.StaticData.LoadIcon("view_shaded.png", 16, 16, theme.InvertIcons),
                [RenderTypes.Outlines]  = AggContext.StaticData.LoadIcon("view_outlines.png", 16, 16, theme.InvertIcons),
                [RenderTypes.Polygons]  = AggContext.StaticData.LoadIcon("view_polygons.png", 16, 16, theme.InvertIcons),
                [RenderTypes.Materials] = AggContext.StaticData.LoadIcon("view_materials.png", 16, 16, theme.InvertIcons),
                [RenderTypes.Overhang]  = AggContext.StaticData.LoadIcon("view_overhang.png", 16, 16, theme.InvertIcons),
            };

            this.AddChild(iconButton = new IconButton(viewIcons[sceneContext.ViewState.RenderType], theme)
            {
                Selectable = false
            });

            UserSettings.Instance.SettingChanged += UserSettings_SettingChanged;
        }
Exemple #16
0
        public PartTabPage(PrinterConfig printer, BedConfig sceneContext, ThemeConfig theme, string tabTitle)
            : base(tabTitle)
        {
            this.sceneContext    = sceneContext;
            this.theme           = theme;
            this.BackgroundColor = theme.BackgroundColor;
            this.Padding         = 0;
            this.printer         = printer;

            bool isPrinterType = this is PrinterTabPage;

            var favoritesBarAndView3DWidget = new FlowLayoutWidget()
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch
            };

            viewControls3D = new ViewControls3D(sceneContext, theme, sceneContext.Scene.UndoBuffer, isPrinterType, !(this is PrinterTabPage))
            {
                VAnchor = VAnchor.Top | VAnchor.Fit,
                HAnchor = HAnchor.Left | HAnchor.Stretch,
                Visible = true,
            };
            theme.ApplyBottomBorder(viewControls3D, shadedBorder: (this is PrinterTabPage));             // Shade border if toolbar is secondary rather than primary

            viewControls3D.ResetView += (sender, e) =>
            {
                if (view3DWidget.Visible)
                {
                    this.view3DWidget.ResetView();
                }
            };
            viewControls3D.ExtendOverflowMenu  = this.GetViewControls3DOverflowMenu;
            viewControls3D.OverflowButton.Name = "View3D Overflow Menu";

            // The 3D model view
            view3DWidget = new View3DWidget(
                printer,
                sceneContext,
                viewControls3D,
                theme,
                this,
                editorType: (isPrinterType) ? MeshViewerWidget.EditorType.Printer : MeshViewerWidget.EditorType.Part);

            viewControls3D.SetView3DWidget(view3DWidget);

            this.AddChild(topToBottom = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch
            });

            topToBottom.AddChild(leftToRight = new FlowLayoutWidget()
            {
                Name    = "View3DContainerParent",
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch
            });

            view3DContainer = new GuiWidget()
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch
            };

            var toolbarAndView3DWidget = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch
            };

            toolbarAndView3DWidget.AddChild(viewControls3D);

            var favoritesBarContext = new LibraryConfig()
            {
                ActiveContainer = ApplicationController.Instance.Library.RootLibaryContainer
            };

            var leftBar = new GuiWidget()
            {
                VAnchor     = VAnchor.Stretch,
                HAnchor     = HAnchor.Fit,
                Border      = new BorderDouble(top: 1, right: 1),
                BorderColor = theme.BorderColor20,
            };

            favoritesBarAndView3DWidget.AddChild(leftBar);

            bool expanded = UserSettings.Instance.get(UserSettingsKey.FavoritesBarExpansion) != "0";

            favoritesBar = new LibraryListView(favoritesBarContext, theme)
            {
                Name = "LibraryView",
                // Drop containers
                ContainerFilter  = (container) => false,
                HAnchor          = HAnchor.Absolute,
                VAnchor          = VAnchor.Stretch,
                AllowContextMenu = false,

                // restore to state for favorites bar size
                Width           = expanded ? 55 : 33,
                ListContentView = new IconView(theme, expanded ? 48 : 24)
                {
                    VAnchor = VAnchor.Fit | VAnchor.Top
                },
            };
            leftBar.AddChild(favoritesBar);

            favoritesBar.ScrollArea.VAnchor = VAnchor.Fit;

            var expandedImage  = AggContext.StaticData.LoadIcon("expand.png", 16, 16, theme.InvertIcons);
            var collapsedImage = AggContext.StaticData.LoadIcon("collapse.png", 16, 16, theme.InvertIcons);

            var expandBarButton = new IconButton(expanded ? collapsedImage : expandedImage, theme)
            {
                HAnchor = HAnchor.Center,
                VAnchor = VAnchor.Absolute | VAnchor.Bottom,
                Margin  = new BorderDouble(bottom: 3, top: 3),
                Height  = theme.ButtonHeight - 6,
                Width   = theme.ButtonHeight - 6
            };

            expandBarButton.Click += (s, e) => UiThread.RunOnIdle(() =>
            {
                expanded = !expanded;

                UserSettings.Instance.set(UserSettingsKey.FavoritesBarExpansion, expanded ? "1" : "0");

                favoritesBar.ListContentView = new IconView(theme, expanded ? 48 : 24);
                favoritesBar.Width           = expanded ? 55 : 33;
                expandBarButton.SetIcon(expanded ? collapsedImage : expandedImage);
                expandBarButton.Invalidate();

                favoritesBar.Reload().ConfigureAwait(false);
            });
            leftBar.AddChild(expandBarButton);

            favoritesBar.Margin = new BorderDouble(bottom: expandBarButton.Height + expandBarButton.Margin.Height);

            favoritesBarAndView3DWidget.AddChild(view3DWidget);
            toolbarAndView3DWidget.AddChild(favoritesBarAndView3DWidget);

            view3DContainer.AddChild(toolbarAndView3DWidget);

            leftToRight.AddChild(view3DContainer);

            if (sceneContext.World.RotationMatrix == Matrix4X4.Identity)
            {
                this.view3DWidget.ResetView();
            }

            this.AnchorAll();
        }
        public static async void DuplicateItem(this BedConfig sceneContext, double xOffset, IObject3D sourceItem = null)
        {
            var scene = sceneContext.Scene;

            if (sourceItem == null)
            {
                var selectedItem = scene.SelectedItem;
                if (selectedItem != null)
                {
                    sourceItem = selectedItem;
                }
            }

            if (sourceItem != null)
            {
                // Copy selected item
                IObject3D newItem = await Task.Run(() =>
                {
                    if (sourceItem != null)
                    {
                        if (sourceItem is SelectionGroupObject3D)
                        {
                            // the selection is a group of objects that need to be copied
                            var copyList       = sourceItem.Children.ToList();
                            scene.SelectedItem = null;
                            foreach (var item in copyList)
                            {
                                var clonedItem = item.Clone();
                                clonedItem.Translate(xOffset);
                                // make the name unique
                                var newName     = agg_basics.GetNonCollidingName(item.Name, scene.DescendantsAndSelf().Select((d) => d.Name));
                                clonedItem.Name = newName;
                                // add it to the scene
                                scene.Children.Add(clonedItem);
                                // add it to the selection
                                scene.AddToSelection(clonedItem);
                            }
                        }
                        else                         // the selection can be cloned easily
                        {
                            var clonedItem = sourceItem.Clone();

                            clonedItem.Translate(xOffset);
                            // make the name unique
                            var newName     = agg_basics.GetNonCollidingName(sourceItem.Name, scene.DescendantsAndSelf().Select((d) => d.Name));
                            clonedItem.Name = newName;

                            // More useful if it creates the part in the exact position and then the user can move it.
                            // Consistent with other software as well. LBB 2017-12-02
                            //PlatingHelper.MoveToOpenPositionRelativeGroup(clonedItem, Scene.Children);

                            return(clonedItem);
                        }
                    }

                    return(null);
                });

                // it might come back null due to threading
                if (newItem != null)
                {
                    sceneContext.InsertNewItem(newItem);
                }
            }
        }
Exemple #18
0
        public GCodeOptionsPanel(BedConfig sceneContext, PrinterConfig printer, ThemeConfig theme)
            : base(FlowDirection.TopToBottom)
        {
            gcodeOptions = sceneContext.RendererOptions;

            var buttonPanel = new FlowLayoutWidget()
            {
                HAnchor = HAnchor.Fit,
                VAnchor = VAnchor.Fit
            };

            var buttonGroup = new ObservableCollection <GuiWidget>();

            speedsButton = new RadioIconButton(AggContext.StaticData.LoadIcon("speeds.png", theme.InvertIcons), theme)
            {
                SiblingRadioButtonList = buttonGroup,
                Name        = "Speeds Button",
                Checked     = gcodeOptions.GCodeLineColorStyle == "Speeds",
                ToolTipText = "Show Speeds".Localize(),
                Margin      = theme.ButtonSpacing
            };
            speedsButton.Click += SwitchColorModes_Click;
            buttonGroup.Add(speedsButton);

            buttonPanel.AddChild(speedsButton);

            materialsButton = new RadioIconButton(AggContext.StaticData.LoadIcon("materials.png", theme.InvertIcons), theme)
            {
                SiblingRadioButtonList = buttonGroup,
                Name        = "Materials Button",
                Checked     = gcodeOptions.GCodeLineColorStyle == "Materials",
                ToolTipText = "Show Materials".Localize(),
                Margin      = theme.ButtonSpacing
            };
            materialsButton.Click += SwitchColorModes_Click;
            buttonGroup.Add(materialsButton);

            buttonPanel.AddChild(materialsButton);

            noColorButton = new RadioIconButton(AggContext.StaticData.LoadIcon("no-color.png", theme.InvertIcons), theme)
            {
                SiblingRadioButtonList = buttonGroup,
                Name        = "No Color Button",
                Checked     = gcodeOptions.GCodeLineColorStyle == "None",
                ToolTipText = "No Color".Localize(),
                Margin      = theme.ButtonSpacing
            };
            noColorButton.Click += SwitchColorModes_Click;
            buttonGroup.Add(noColorButton);

            buttonPanel.AddChild(noColorButton);

            this.AddChild(
                new SettingsItem(
                    "Color View".Localize(),
                    theme,
                    optionalControls: buttonPanel,
                    enforceGutter: false));

            buttonPanel = new FlowLayoutWidget()
            {
                HAnchor = HAnchor.Fit,
                VAnchor = VAnchor.Fit
            };

            // Reset to new button group
            buttonGroup = new ObservableCollection <GuiWidget>();

            solidButton = new RadioIconButton(AggContext.StaticData.LoadIcon("solid.png", theme.InvertIcons), theme)
            {
                SiblingRadioButtonList = buttonGroup,
                Name        = "Solid Button",
                Checked     = gcodeOptions.GCodeModelView == "Semi-Transparent",
                ToolTipText = "Show Semi-Transparent Model".Localize(),
                Margin      = theme.ButtonSpacing
            };
            solidButton.Click += SwitchModelModes_Click;
            buttonGroup.Add(solidButton);

            buttonPanel.AddChild(solidButton);

            materialsButton = new RadioIconButton(AggContext.StaticData.LoadIcon("wireframe.png", theme.InvertIcons), theme)
            {
                SiblingRadioButtonList = buttonGroup,
                Name        = "Wireframe Button",
                Checked     = gcodeOptions.GCodeModelView == "Wireframe",
                ToolTipText = "Show Wireframe Model".Localize(),
                Margin      = theme.ButtonSpacing
            };
            materialsButton.Click += SwitchModelModes_Click;
            buttonGroup.Add(materialsButton);

            buttonPanel.AddChild(materialsButton);

            noColorButton = new RadioIconButton(AggContext.StaticData.LoadIcon("no-color.png", theme.InvertIcons), theme)
            {
                SiblingRadioButtonList = buttonGroup,
                Name        = "No Model Button",
                Checked     = gcodeOptions.GCodeModelView == "None",
                ToolTipText = "No Model".Localize(),
                Margin      = theme.ButtonSpacing
            };
            noColorButton.Click += SwitchModelModes_Click;
            buttonGroup.Add(noColorButton);

            buttonPanel.AddChild(noColorButton);

            this.AddChild(
                new SettingsItem(
                    "Model View".Localize(),
                    buttonPanel,
                    theme,
                    enforceGutter: false));

            gcodeOptions = sceneContext.RendererOptions;

            var viewOptions = sceneContext.GetBaseViewOptions();

            viewOptions.AddRange(new[]
            {
                new BoolOption(
                    "Moves".Localize(),
                    () => gcodeOptions.RenderMoves,
                    (value) => gcodeOptions.RenderMoves = value),
                new BoolOption(
                    "Retractions".Localize(),
                    () => gcodeOptions.RenderRetractions,
                    (value) => gcodeOptions.RenderRetractions = value),
                new BoolOption(
                    "Extrusion".Localize(),
                    () => gcodeOptions.SimulateExtrusion,
                    (value) => gcodeOptions.SimulateExtrusion = value),
                new BoolOption(
                    "Transparent".Localize(),
                    () => gcodeOptions.TransparentExtrusion,
                    (value) => gcodeOptions.TransparentExtrusion = value),
                new BoolOption(
                    "Hide Offsets".Localize(),
                    () => gcodeOptions.HideExtruderOffsets,
                    (value) => gcodeOptions.HideExtruderOffsets = value,
                    () => printer.Settings.GetValue <int>(SettingsKey.extruder_count) > 1),
                new BoolOption(
                    "Sync To Print".Localize(),
                    () => gcodeOptions.SyncToPrint,
                    (value) =>
                {
                    gcodeOptions.SyncToPrint = value;
                    if (!gcodeOptions.SyncToPrint)
                    {
                        // If we are turning off sync to print, set the slider to full.
                        //layerRenderRatioSlider.SecondValue = 1;
                    }
                })
            });

            var optionsContainer = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit
            };

            this.AddChild(optionsContainer);

            void BuildMenu()
            {
                foreach (var option in viewOptions.Where(option => option.IsVisible()))
                {
                    var settingsItem = new SettingsItem(
                        option.Title,
                        theme,
                        new SettingsItem.ToggleSwitchConfig()
                    {
                        Name         = option.Title + " Toggle",
                        Checked      = option.IsChecked(),
                        ToggleAction = option.SetValue
                    },
                        enforceGutter: false);

                    settingsItem.Padding = settingsItem.Padding.Clone(right: 8);

                    optionsContainer.AddChild(settingsItem);
                }
            }

            BuildMenu();

            PropertyChangedEventHandler syncProperties = (s, e) =>
            {
                if (e.PropertyName == nameof(gcodeOptions.RenderBed) ||
                    e.PropertyName == nameof(gcodeOptions.RenderBuildVolume))
                {
                    optionsContainer.CloseAllChildren();
                    BuildMenu();
                }
            };

            gcodeOptions.PropertyChanged += syncProperties;

            optionsContainer.Closed += (s, e) =>
            {
                gcodeOptions.PropertyChanged -= syncProperties;
            };
        }
        public SelectedObjectPanel(View3DWidget view3DWidget, BedConfig sceneContext, ThemeConfig theme)
            : base(FlowDirection.TopToBottom)
        {
            this.HAnchor      = HAnchor.Stretch;
            this.VAnchor      = VAnchor.Top | VAnchor.Fit;
            this.Padding      = 0;
            this.view3DWidget = view3DWidget;
            this.theme        = theme;
            this.sceneContext = sceneContext;

            this.ContentPanel = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit,
            };

            var scrollable = new ScrollableWidget(true)
            {
                Name    = "editorPanel",
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch,
            };

            scrollable.AddChild(this.ContentPanel);
            scrollable.ScrollArea.HAnchor = HAnchor.Stretch;

            this.AddChild(scrollable);

            var toolbar = new LeftClipFlowLayoutWidget()
            {
                BackgroundColor = theme.TabBodyBackground,
                Padding         = theme.ToolbarPadding,
                HAnchor         = HAnchor.Fit,
                VAnchor         = VAnchor.Fit
            };

            var scene = sceneContext.Scene;

            // put in a make permanent button
            var icon        = AggContext.StaticData.LoadIcon("fa-check_16.png", 16, 16, theme.InvertIcons).SetPreMultiply();
            var applyButton = new IconButton(icon, theme)
            {
                Margin      = theme.ButtonSpacing,
                ToolTipText = "Apply operation and make permanent".Localize()
            };

            applyButton.Click += (s, e) =>
            {
                this.item.Apply(view3DWidget.Scene.UndoBuffer);
                scene.SelectedItem = null;
            };
            scene.SelectionChanged += (s, e) => applyButton.Enabled = scene.SelectedItem?.CanApply == true;
            toolbar.AddChild(applyButton);

            // put in a remove button
            var removeButton = new IconButton(AggContext.StaticData.LoadIcon("close.png", 16, 16, theme.InvertIcons), theme)
            {
                Margin      = theme.ButtonSpacing,
                ToolTipText = "Remove operation from parts".Localize()
            };

            removeButton.Click += (s, e) =>
            {
                item.Remove(view3DWidget.Scene.UndoBuffer);
                scene.SelectedItem = null;
            };
            scene.SelectionChanged += (s, e) => removeButton.Enabled = scene.SelectedItem?.CanRemove == true;
            toolbar.AddChild(removeButton);

            var overflowButton = new OverflowBar.OverflowMenuButton(theme);

            overflowButton.PopupBorderColor    = ApplicationController.Instance.MenuTheme.GetBorderColor(120);
            overflowButton.DynamicPopupContent = () =>
            {
                var popupMenu = new PopupMenu(ApplicationController.Instance.MenuTheme);

                var menuItem = popupMenu.CreateMenuItem("Rename");
                menuItem.Click += (s, e) =>
                {
                    DialogWindow.Show(
                        new InputBoxPage(
                            "Rename Item".Localize(),
                            "Name".Localize(),
                            item.Name,
                            "Enter New Name Here".Localize(),
                            "Rename".Localize(),
                            (newName) =>
                    {
                        item.Name = newName;
                        editorSectionWidget.Text = newName;
                    }));
                };

                popupMenu.CreateHorizontalLine();

                if (true)                 //allowOperations)
                {
                    var selectedItemType = item.GetType();
                    var selectedItem     = item;

                    foreach (var nodeOperation in ApplicationController.Instance.Graph.Operations)
                    {
                        foreach (var type in nodeOperation.MappedTypes)
                        {
                            if (type.IsAssignableFrom(selectedItemType) &&
                                (nodeOperation.IsVisible?.Invoke(selectedItem) != false) &&
                                nodeOperation.IsEnabled?.Invoke(selectedItem) != false)
                            {
                                var button = popupMenu.CreateMenuItem(nodeOperation.Title, nodeOperation.IconCollector?.Invoke()?.CreateScaledImage(16, 16));
                                button.Click += (s, e) =>
                                {
                                    nodeOperation.Operation(selectedItem, sceneContext.Scene).ConfigureAwait(false);
                                };
                            }
                        }
                    }
                }

                return(popupMenu);
            };
            toolbar.AddChild(overflowButton);

            editorPanel = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit,
                Padding = new BorderDouble(top: 10)
            };

            // Wrap editorPanel with scrollable container
            var scrollableWidget = new ScrollableWidget(true)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch
            };

            scrollableWidget.AddChild(editorPanel);
            scrollableWidget.ScrollArea.HAnchor = HAnchor.Stretch;

            editorSectionWidget = new ResizableSectionWidget("Editor", sceneContext.ViewState.SelectedObjectEditorHeight, scrollableWidget, theme, serializationKey: UserSettingsKey.EditorPanelExpanded, rightAlignedContent: toolbar, defaultExpansion: true)
            {
                VAnchor = VAnchor.Fit,
            };
            editorSectionWidget.Resized += (s, e) =>
            {
                sceneContext.ViewState.SelectedObjectEditorHeight = editorSectionWidget.ResizeContainer.Height;
            };

            this.ContentPanel.AddChild(editorSectionWidget);

            var colorSection = new SectionWidget(
                "Color".Localize(),
                new ColorSwatchSelector(scene, theme, buttonSize: 16, buttonSpacing: new BorderDouble(1, 1, 0, 0))
            {
                Margin = new BorderDouble(left: 10)
            },
                theme,
                serializationKey: UserSettingsKey.ColorPanelExpanded)
            {
                Name = "Color Panel",
            };

            this.ContentPanel.AddChild(colorSection);

            var materialsSection = new SectionWidget("Materials".Localize(), new MaterialControls(scene, theme), theme, serializationKey: UserSettingsKey.MaterialsPanelExpanded)
            {
                Name = "Materials Panel",
            };

            this.ContentPanel.AddChild(materialsSection);

            // Enforce panel padding in sidebar
            foreach (var sectionWidget in this.ContentPanel.Children <SectionWidget>())
            {
                // Special case for editorResizeWrapper due to ResizeContainer
                if (sectionWidget is ResizableSectionWidget resizableSectionWidget)
                {
                    // Apply padding to ResizeContainer not wrapper
                    resizableSectionWidget.ResizeContainer.Padding = new BorderDouble(10, 10, 10, 0);
                }
                else
                {
                    sectionWidget.ContentPanel.Padding   = new BorderDouble(10, 10, 10, 0);
                    sectionWidget.ExpandableWhenDisabled = true;
                    sectionWidget.Enabled = false;
                }
            }
        }
Exemple #20
0
        public PartTabPage(PrinterConfig printer, BedConfig sceneContext, ThemeConfig theme, string tabTitle)
            : base(tabTitle)
        {
            this.sceneContext    = sceneContext;
            this.theme           = theme;
            this.BackgroundColor = theme.ActiveTabColor;
            this.Padding         = 0;
            this.printer         = printer;

            bool isPrinterType = this is PrinterTabPage;

            viewControls3D = new ViewControls3D(sceneContext, theme, sceneContext.Scene.UndoBuffer, isPrinterType)
            {
                VAnchor = VAnchor.Top | VAnchor.Fit,
                HAnchor = HAnchor.Left | HAnchor.Stretch,
                Visible = true,
            };
            theme.ApplyBottomBorder(viewControls3D, shadedBorder: (this is PrinterTabPage));             // Shade border if toolbar is secondary rather than primary

            viewControls3D.ResetView += (sender, e) =>
            {
                if (view3DWidget.Visible)
                {
                    this.view3DWidget.ResetView();
                }
            };
            viewControls3D.ExtendOverflowMenu  = this.GetViewControls3DOverflowMenu;
            viewControls3D.OverflowButton.Name = "View3D Overflow Menu";

            // The 3D model view
            view3DWidget = new View3DWidget(
                printer,
                sceneContext,
                viewControls3D,
                theme,
                this,
                editorType: (isPrinterType) ? MeshViewerWidget.EditorType.Printer : MeshViewerWidget.EditorType.Part);

            viewControls3D.SetView3DWidget(view3DWidget);

            // Construct and store dictionary of menu actions accessible at workspace level
            view3DWidget.WorkspaceActions = viewControls3D.MenuActions.Where(o => !string.IsNullOrEmpty(o.ID)).ToDictionary(o => o.ID, o => o);

            this.AddChild(topToBottom = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch
            });

            topToBottom.AddChild(leftToRight = new FlowLayoutWidget()
            {
                Name    = "View3DContainerParent",
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch
            });

            view3DContainer = new GuiWidget()
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch
            };

            var toolbarAndView3DWidget = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch
            };

            toolbarAndView3DWidget.AddChild(viewControls3D);
            toolbarAndView3DWidget.AddChild(view3DWidget);
            view3DContainer.AddChild(toolbarAndView3DWidget);

            leftToRight.AddChild(view3DContainer);

            view3DWidget.BackgroundColor = ActiveTheme.Instance.TertiaryBackgroundColor;

            if (sceneContext.World.RotationMatrix == Matrix4X4.Identity)
            {
                this.view3DWidget.ResetView();
            }

            this.AnchorAll();
        }
Exemple #21
0
        public async Task ResavedSceneRemainsConsistent()
        {
#if !__ANDROID__
            // Set the static data to point to the directory of MatterControl
            AggContext.StaticData = new FileSystemStaticData(TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"));
            MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4));
#endif
            AssetObject3D.AssetManager = new AssetManager();

            var sceneContext = new BedConfig(null);

            var scene = sceneContext.Scene;
            scene.Children.Add(new Object3D
            {
                Mesh = PlatonicSolids.CreateCube(20, 20, 20)
            });

            string tempPath = GetSceneTempPath();
            string filePath = Path.Combine(tempPath, "some.mcx");

            // Set directory for asset resolution
            Object3D.AssetsPath = Path.Combine(tempPath, "Assets");
            Directory.CreateDirectory(Object3D.AssetsPath);

            // Empty temp folder
            foreach (string tempFile in Directory.GetFiles(Object3D.AssetsPath).ToList())
            {
                File.Delete(tempFile);
            }

            scene.Save(filePath);
            Assert.AreEqual(1, Directory.GetFiles(tempPath).Length, "Only .mcx file should exists");
            Assert.AreEqual(1, Directory.GetFiles(Path.Combine(tempPath, "Assets")).Length, "Only 1 asset should exist");

            var originalFiles = Directory.GetFiles(tempPath).ToArray();

            // Load the file from disk
            IObject3D loadedItem = Object3D.Load(filePath, CancellationToken.None);
            Assert.AreEqual(1, loadedItem.Children.Count);

            // Ensure the UI scene is cleared
            scene.Children.Modify(list => list.Clear());

            // Reload the model
            await Task.Run(() =>
            {
                sceneContext.Scene.Load(Object3D.Load(filePath, CancellationToken.None));
            });

            // Serialize and compare the two trees
            string onDiskData   = loadedItem.ToJson();
            string inMemoryData = scene.ToJson();

            //File.WriteAllText(@"c:\temp\file-a.txt", onDiskData);
            //File.WriteAllText(@"c:\temp\file-b.txt", inMemoryData);

            Assert.AreEqual(inMemoryData, onDiskData, "Serialized content should match");
            Object3D.AssetsPath = Path.Combine(tempPath, "Assets");

            // Save the scene a second time, validate that things remain the same
            scene.Save(filePath);
            onDiskData = loadedItem.ToJson();

            Assert.IsTrue(inMemoryData == onDiskData);

            // Verify that no additional files get created on second save
            Assert.AreEqual(1, Directory.GetFiles(tempPath).Length, "Only .mcx file should exists");
            Assert.AreEqual(1, Directory.GetFiles(Path.Combine(tempPath, "Assets")).Length, "Only 1 asset should exist");
        }
Exemple #22
0
        public override void Load()
        {
            var library = ApplicationController.Instance.Library;

            long index        = DateTime.Now.Ticks;
            var  libraryItems = new List <GeneratorItem>()
            {
                new GeneratorItem(
                    () => "Cube".Localize(),
                    async() => await CubeObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Pyramid".Localize(),
                    async() => await PyramidObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Wedge".Localize(),
                    async() => await WedgeObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Half Wedge".Localize(),
                    async() => await HalfWedgeObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Text".Localize(),
                    async() => await TextObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },

                new GeneratorItem(
                    () => "Cylinder".Localize(),
                    async() => await CylinderObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Cone".Localize(),
                    async() => await ConeObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Half Cylinder".Localize(),
                    async() => await HalfCylinderObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Torus".Localize(),
                    async() => await TorusObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Ring".Localize(),
                    async() => await RingObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Sphere".Localize(),
                    async() => await SphereObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Half Sphere".Localize(),
                    async() => await HalfSphereObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
#if DEBUG
                new GeneratorItem(
                    () => "XY Calibration".Localize(),
                    async() => await XyCalibrationFaceObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
#endif
                new GeneratorItem(
                    () => "Image Converter".Localize(),
                    () =>
                {
                    // Construct an image
                    var imageObject = new ImageObject3D()
                    {
                        AssetPath = AggContext.StaticData.ToAssetPath(Path.Combine("Images", "mh-logo.png"))
                    };

                    // Construct a scene
                    var bedConfig = new BedConfig(null);
                    var tempScene = bedConfig.Scene;
                    tempScene.Children.Add(imageObject);
                    tempScene.SelectedItem = imageObject;

                    // Invoke ImageConverter operation, passing image and scene
                    SceneOperations.ById("ImageConverter").Action(bedConfig);

                    // Return replacement object constructed in ImageConverter operation
                    var constructedComponent = tempScene.SelectedItem;
                    tempScene.Children.Remove(constructedComponent);

                    return(Task.FromResult <IObject3D>(constructedComponent));
                })
                {
                    DateCreated = new System.DateTime(index++)
                },
                new GeneratorItem(
                    () => "Measure Tool".Localize(),
                    async() => await MeasureToolObject3D.Create())
                {
                    DateCreated = new System.DateTime(index++)
                },
            };

            string title = "Primitive Shapes".Localize();

            foreach (var item in libraryItems)
            {
                item.Category = title;
                Items.Add(item);
            }
        }
Exemple #23
0
        public PartsBar(PartPreviewContent partPreviewContent, ThemeConfig theme)
            : base("Parts".Localize(), theme)
        {
            var emptyPlateButton = new ImageWidget(AggContext.StaticData.LoadIcon("new-part.png", 70, 70))
            {
                Margin          = new BorderDouble(right: 5),
                Selectable      = true,
                BackgroundColor = theme.MinimalShade,
                Cursor          = Cursors.Hand,
                Name            = "Create Part Button"
            };

            emptyPlateButton.Click += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    UiThread.RunOnIdle(async() =>
                    {
                        var workspace = new BedConfig();
                        await workspace.LoadContent(
                            new EditContext()
                        {
                            ContentStore = ApplicationController.Instance.Library.PartHistory,
                            SourceItem   = BedConfig.NewPlatingItem(ApplicationController.Instance.Library.PartHistory)
                        });

                        ApplicationController.Instance.Workspaces.Add(workspace);

                        partPreviewContent.CreatePartTab("New Part", workspace, theme);
                    });
                }
            };
            toolbar.AddChild(emptyPlateButton);

            var recentParts = new DirectoryInfo(ApplicationDataStorage.Instance.PartHistoryDirectory).GetFiles("*.mcx").OrderByDescending(f => f.LastWriteTime);

            foreach (var item in recentParts.Where(f => f.Length > 500).Select(f => new SceneReplacementFileItem(f.FullName)).Take(10).ToList <ILibraryItem>())
            {
                var iconButton = new IconViewItem(new ListViewItem(item, ApplicationController.Instance.Library.PlatingHistory), 70, 70, theme)
                {
                    Margin     = new BorderDouble(right: 5),
                    Selectable = true,
                };

                iconButton.Click += async(s, e) =>
                {
                    // Activate selected item tab
                    if (partPreviewContent.TabControl.AllTabs.FirstOrDefault(t => t.Text == item.Name) is ChromeTab existingItemTab)
                    {
                        partPreviewContent.TabControl.ActiveTab = existingItemTab;
                    }
                    else
                    {
                        // Create tab for selected item
                        if (this.PositionWithinLocalBounds(e.X, e.Y) &&
                            e.Button == MouseButtons.Left)
                        {
                            var workspace = new BedConfig();
                            await workspace.LoadContent(
                                new EditContext()
                            {
                                ContentStore = ApplicationController.Instance.Library.PartHistory,
                                SourceItem   = item
                            });

                            ApplicationController.Instance.Workspaces.Add(workspace);

                            partPreviewContent.CreatePartTab(item.Name, workspace, theme);
                        }
                    }
                };

                toolbar.AddChild(iconButton);
            }
        }
Exemple #24
0
        private void RebuildPlateOptions(PartPreviewContent partPreviewContent, ThemeConfig theme)
        {
            toolbar.ActionArea.CloseAllChildren();

            var lastProfileID = ProfileManager.Instance.LastProfileID;
            var lastProfile   = ProfileManager.Instance[lastProfileID];

            if (lastProfile == null)
            {
                if (ProfileManager.Instance.Profiles.Count > 0)
                {
                    toolbar.AddChild(new TextWidget("Select a printer to continue".Localize() + "...", textColor: theme.Colors.PrimaryTextColor, pointSize: theme.DefaultFontSize)
                    {
                        Margin = 15
                    });
                }
                else
                {
                    toolbar.AddChild(new TextWidget("Create a printer to continue".Localize() + "...", textColor: theme.Colors.PrimaryTextColor, pointSize: theme.DefaultFontSize)
                    {
                        Margin = 15
                    });
                }
            }
            else
            {
                var emptyPlateButton = new ImageWidget(AggContext.StaticData.LoadIcon("empty-workspace.png", 70, 70))
                {
                    Margin          = new BorderDouble(right: 5),
                    Selectable      = true,
                    BackgroundColor = theme.MinimalShade,
                    Name            = "Open Empty Plate Button",
                    Cursor          = Cursors.Hand
                };
                emptyPlateButton.Click += (s, e) =>
                {
                    if (e.Button == MouseButtons.Left)
                    {
                        UiThread.RunOnIdle(async() =>
                        {
                            var printer = await ProfileManager.Instance.LoadPrinter();
                            printer.ViewState.ViewMode = PartViewMode.Model;

                            // Load empty plate
                            await printer.Bed.LoadContent(
                                new EditContext()
                            {
                                ContentStore = ApplicationController.Instance.Library.PlatingHistory,
                                SourceItem   = BedConfig.NewPlatingItem(ApplicationController.Instance.Library.PlatingHistory)
                            });

                            // Always switch to printer tab after changing plate
                            partPreviewContent.TabControl.SelectedTabIndex = 1;
                        });
                    }
                };

                toolbar.AddChild(emptyPlateButton);

                // Select the 25 most recent files and project onto FileSystemItems
                var recentFiles = new DirectoryInfo(ApplicationDataStorage.Instance.PlatingDirectory).GetFiles("*.mcx").OrderByDescending(f => f.LastWriteTime);
                foreach (var item in recentFiles.Where(f => f.Length > 500).Select(f => new SceneReplacementFileItem(f.FullName)).Take(10).ToList <ILibraryItem>())
                {
                    var iconButton = new IconViewItem(new ListViewItem(item, ApplicationController.Instance.Library.PlatingHistory), 70, 70, theme)
                    {
                        Margin     = new BorderDouble(right: 5),
                        Selectable = true,
                        Cursor     = Cursors.Hand
                    };

                    iconButton.Click += (s, e) =>
                    {
                        if (this.PositionWithinLocalBounds(e.X, e.Y) &&
                            e.Button == MouseButtons.Left)
                        {
                            UiThread.RunOnIdle(async() =>
                            {
                                await ProfileManager.Instance.LoadPrinterOpenItem(item);

                                var printer = ApplicationController.Instance.ActivePrinter;
                                printer.ViewState.ViewMode = PartViewMode.Model;

                                // Always switch to printer tab after changing plate
                                partPreviewContent.TabControl.SelectedTabIndex = 1;
                            });
                        }
                    };

                    toolbar.AddChild(iconButton);
                }
            }
        }
        public override void Load()
        {
            var library = ApplicationController.Instance.Library;

            long index        = DateTime.Now.Ticks;
            var  libraryItems = new List <GeneratorItem>()
            {
                new GeneratorItem(
                    () => "Cube".Localize(),
                    async() => await CubeObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Pyramid".Localize(),
                    async() => await PyramidObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Wedge".Localize(),
                    async() => await WedgeObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Half Wedge".Localize(),
                    async() => await HalfWedgeObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Text".Localize(),
                    async() => await TextObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Cylinder".Localize(),
                    async() => await CylinderObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Cone".Localize(),
                    async() => await ConeObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Half Cylinder".Localize(),
                    async() => await HalfCylinderObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Torus".Localize(),
                    async() => await TorusObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Ring".Localize(),
                    async() => await RingObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Sphere".Localize(),
                    async() => await SphereObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Half Sphere".Localize(),
                    async() => await HalfSphereObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
#if DEBUG
                new GeneratorItem(
                    () => "SCAD Script".Localize(),
                    async() => await OpenScadScriptObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "MarchingSquares".Localize(),
                    async() => await MarchingSquaresObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
#endif
                new GeneratorItem(
                    () => "Image Converter".Localize(),
                    () =>
                {
                    // Construct an image
                    var imageObject = new ImageObject3D()
                    {
                        AssetPath = StaticData.Instance.ToAssetPath(Path.Combine("Images", "mh-logo.png"))
                    };

                    // Construct a scene
                    var bedConfig = new BedConfig(null);
                    var tempScene = bedConfig.Scene;
                    tempScene.Children.Add(imageObject);
                    tempScene.SelectedItem = imageObject;

                    // Invoke ImageConverter operation, passing image and scene
                    SceneOperations.ById("ImageConverter").Action(bedConfig);

                    // Return replacement object constructed in ImageConverter operation
                    var constructedComponent = tempScene.SelectedItem;
                    tempScene.Children.Remove(constructedComponent);

                    return(Task.FromResult(constructedComponent));
                })
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Measure Tool".Localize(),
                    async() => await MeasureToolObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Description".Localize(),
                    async() => await DescriptionObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
                new GeneratorItem(
                    () => "Variable Sheet".Localize(),
                    async() => await SheetObject3D.Create())
                {
                    DateCreated = new DateTime(index++)
                },
            };

            string title = "Primitive Shapes".Localize();

            foreach (var item in libraryItems)
            {
                item.Category = title;
                Items.Add(item);
            }

            this.ChildContainers.Add(
                new DynamicContainerLink(
                    () => "Primitives 2D".Localize(),
                    StaticData.Instance.LoadIcon(Path.Combine("Library", "folder.png")),
                    StaticData.Instance.LoadIcon(Path.Combine("Library", "primitives_library_icon.png")),
                    () => new Primitives2DContainer())
            {
                IsReadOnly = true
            });
        }
Exemple #26
0
        private GuiWidget ShowViewOptions(BedConfig sceneContext, ThemeConfig theme)
        {
            var popupMenu = new PopupMenu(ApplicationController.Instance.MenuTheme);

            var siblingList = new List <GuiWidget>();

            popupMenu.CreateBoolMenuItem(
                "Shaded".Localize(),
                viewIcons[RenderTypes.Shaded],
                () => sceneContext.ViewState.RenderType == RenderTypes.Shaded,
                (isChecked) =>
            {
                sceneContext.ViewState.RenderType = RenderTypes.Shaded;
            },
                useRadioStyle: true,
                siblingRadioButtonList: siblingList);

            popupMenu.CreateBoolMenuItem(
                "Outlines".Localize(),
                viewIcons[RenderTypes.Outlines],
                () => sceneContext.ViewState.RenderType == RenderTypes.Outlines,
                (isChecked) =>
            {
                sceneContext.ViewState.RenderType = RenderTypes.Outlines;
            },
                useRadioStyle: true,
                siblingRadioButtonList: siblingList);

            popupMenu.CreateBoolMenuItem(
                "Polygons".Localize(),
                viewIcons[RenderTypes.Polygons],
                () => sceneContext.ViewState.RenderType == RenderTypes.Polygons,
                (isChecked) =>
            {
                sceneContext.ViewState.RenderType = RenderTypes.Polygons;
            },
                useRadioStyle: true,
                siblingRadioButtonList: siblingList);

            popupMenu.CreateBoolMenuItem(
                "Materials".Localize(),
                viewIcons[RenderTypes.Materials],
                () => sceneContext.ViewState.RenderType == RenderTypes.Materials,
                (isChecked) =>
            {
                sceneContext.ViewState.RenderType = RenderTypes.Materials;
            },
                useRadioStyle: true,
                siblingRadioButtonList: siblingList);

            popupMenu.CreateBoolMenuItem(
                "Overhang".Localize(),
                viewIcons[RenderTypes.Overhang],
                () => sceneContext.ViewState.RenderType == RenderTypes.Overhang,
                (isChecked) =>
            {
                sceneContext.ViewState.RenderType = RenderTypes.Overhang;
            },
                useRadioStyle: true,
                siblingRadioButtonList: siblingList);

            // Override menu left padding to improve radio circle -> icon spacing
            foreach (var menuItem in popupMenu.Children)
            {
                menuItem.Padding = menuItem.Padding.Clone(left: 25);
            }

            return(popupMenu);
        }
        public override async Task <long> SubmitAddChangeRequestAsync(VehicleToBedConfig entity, string requestedBy,
                                                                      List <ChangeRequestItemStaging> changeRequestItemStagings = null, CommentsStagingModel comment = null,
                                                                      List <AttachmentsModel> attachmentsStagingModels          = null, string changeContent = null)
        {
            if (entity.VehicleId.Equals(default(int)) ||
                entity.BedConfigId.Equals(default(int)))
            {
                throw new ArgumentException(nameof(entity));
            }

            changeRequestItemStagings = changeRequestItemStagings ?? new List <ChangeRequestItemStaging>();
            // Validation check for insert of new vehicle to Bed config

            StringBuilder validationErrorMessage = new StringBuilder();

            await ValidateVehicleToBedConfigHasNoChangeReqeuest(entity);
            await ValidateVehicleToBedConfigLookUpHasNoChangeRequest(entity);

            changeRequestItemStagings.Add(new ChangeRequestItemStaging()
            {
                ChangeType      = ChangeType.Add,
                EntityId        = entity.Id.ToString(),
                CreatedDateTime = DateTime.UtcNow,
                Entity          = typeof(VehicleToBedConfig).Name,
                Payload         = base.Serializer.Serialize(entity)
            });

            var vehicleRepositoryService   = Repositories.GetRepositoryService <Vehicle>() as IVcdbSqlServerEfRepositoryService <Vehicle>;
            var bedConfigRepositoryService = Repositories.GetRepositoryService <BedConfig>() as IVcdbSqlServerEfRepositoryService <BedConfig>;

            Vehicle   vehicle   = null;
            BedConfig bedConfig = null;

            if (vehicleRepositoryService != null && bedConfigRepositoryService != null)
            {
                var vehicles = await vehicleRepositoryService.GetAsync(m => m.Id == entity.VehicleId && m.DeleteDate == null, 1);

                if (vehicles != null && vehicles.Any())
                {
                    vehicle = vehicles.First();
                }

                var bedConfigs = await bedConfigRepositoryService.GetAsync(m => m.Id == entity.BedConfigId && m.DeleteDate == null, 1);

                if (bedConfigs != null && bedConfigs.Any())
                {
                    bedConfig = bedConfigs.First();
                }
            }

            changeContent = string.Format("{0} / {1} / {2} / {3} / {4} => \n{5} / {6} / {7}"
                                          , vehicle.BaseVehicle.YearId
                                          , vehicle.BaseVehicle.Make.Name
                                          , vehicle.BaseVehicle.Model.Name
                                          , vehicle.SubModel.Name
                                          , vehicle.Region.Name
                                          , bedConfig.BedLength.Length
                                          , bedConfig.BedLength.BedLengthMetric
                                          , bedConfig.BedType.Name);

            // NOTE: change-request-comments-staging perfomed on base

            return(await base.SubmitAddChangeRequestAsync(entity, requestedBy, changeRequestItemStagings, comment, attachmentsStagingModels, changeContent));
        }
Exemple #28
0
        public SelectedObjectPanel(View3DWidget view3DWidget, BedConfig sceneContext, ThemeConfig theme)
            : base(FlowDirection.TopToBottom)
        {
            this.HAnchor      = HAnchor.Stretch;
            this.VAnchor      = VAnchor.Top | VAnchor.Fit;
            this.Padding      = 0;
            this.view3DWidget = view3DWidget;
            this.theme        = theme;
            this.sceneContext = sceneContext;

            var toolbar = new LeftClipFlowLayoutWidget()
            {
                BackgroundColor = theme.ActiveTabColor,
                Padding         = theme.ToolbarPadding,
                HAnchor         = HAnchor.Fit,
                VAnchor         = VAnchor.Fit
            };

            var scene = sceneContext.Scene;

            // put in a make permanent button
            var icon          = AggContext.StaticData.LoadIcon("noun_766157.png", 16, 16, theme.InvertIcons).SetPreMultiply();
            var flattenButton = new IconButton(icon, theme)
            {
                Margin      = theme.ButtonSpacing,
                ToolTipText = "Flatten".Localize(),
                Enabled     = scene.SelectedItem?.CanFlatten == true
            };

            flattenButton.Click += (s, e) =>
            {
                this.item.Flatten(view3DWidget.Scene.UndoBuffer);
                scene.SelectedItem = null;
            };
            toolbar.AddChild(flattenButton);

            // put in a remove button
            var removeButton = new IconButton(AggContext.StaticData.LoadIcon("remove.png", 16, 16, theme.InvertIcons), theme)
            {
                Margin      = theme.ButtonSpacing,
                ToolTipText = "Delete".Localize(),
                Enabled     = scene.SelectedItem != null
            };

            removeButton.Click += (s, e) =>
            {
                var rootSelection = scene.SelectedItemRoot;

                var removeItem = item;
                removeItem.Remove(view3DWidget.Scene.UndoBuffer);

                scene.SelectedItem = null;

                // Only restore the root selection if it wasn't the item removed
                if (removeItem != rootSelection)
                {
                    scene.SelectedItem = rootSelection;
                }
            };
            toolbar.AddChild(removeButton);

            var overflowButton = new OverflowBar.OverflowMenuButton(theme)
            {
                Enabled          = scene.SelectedItem != null,
                PopupBorderColor = ApplicationController.Instance.MenuTheme.GetBorderColor(120)
            };

            overflowButton.DynamicPopupContent = () =>
            {
                return(ApplicationController.Instance.GetActionMenuForSceneItem(item, sceneContext.Scene, false));
            };
            toolbar.AddChild(overflowButton);

            editorPanel = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit,
                Name    = "editorPanel",
                Padding = new BorderDouble(right: theme.DefaultContainerPadding + 1)
            };

            // Wrap editorPanel with scrollable container
            var scrollableWidget = new ScrollableWidget(true)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch
            };

            scrollableWidget.AddChild(editorPanel);
            scrollableWidget.ScrollArea.HAnchor = HAnchor.Stretch;

            editorSectionWidget = new SectionWidget("Editor", scrollableWidget, theme, toolbar, expandingContent: false, defaultExpansion: true, setContentVAnchor: false)
            {
                VAnchor = VAnchor.Stretch
            };
            this.AddChild(editorSectionWidget);

            this.ContentPanel   = editorPanel;
            editorPanel.Padding = new BorderDouble(theme.DefaultContainerPadding, 0);

            scene.SelectionChanged += (s, e) =>
            {
                if (editorPanel.Children.FirstOrDefault()?.DescendantsAndSelf <SectionWidget>().FirstOrDefault() is SectionWidget firstSectionWidget)
                {
                    firstSectionWidget.Margin = firstSectionWidget.Margin.Clone(top: 0);
                }

                var selectedItem = scene.SelectedItem;

                flattenButton.Enabled  = selectedItem?.CanFlatten == true;
                removeButton.Enabled   = selectedItem != null;
                overflowButton.Enabled = selectedItem != null;
            };
        }
Exemple #29
0
        public SelectedObjectPanel(View3DWidget view3DWidget, BedConfig sceneContext, ThemeConfig theme)
            : base(FlowDirection.TopToBottom)
        {
            this.HAnchor      = HAnchor.Stretch;
            this.VAnchor      = VAnchor.Top | VAnchor.Fit;
            this.Padding      = 0;
            this.view3DWidget = view3DWidget;
            this.theme        = theme;
            this.sceneContext = sceneContext;

            this.ContentPanel = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit,
            };

            var scrollable = new ScrollableWidget(true)
            {
                Name    = "editorPanel",
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch,
            };

            scrollable.AddChild(this.ContentPanel);
            scrollable.ScrollArea.HAnchor = HAnchor.Stretch;

            this.AddChild(scrollable);

            var toolbar = new LeftClipFlowLayoutWidget()
            {
                BackgroundColor = theme.TabBodyBackground,
                Padding         = theme.ToolbarPadding,
                HAnchor         = HAnchor.Fit,
                VAnchor         = VAnchor.Fit
            };

            var scene = sceneContext.Scene;

            // put in a make permanent button
            var icon        = AggContext.StaticData.LoadIcon("fa-check_16.png", 16, 16, theme.InvertIcons).SetPreMultiply();
            var applyButton = new IconButton(icon, theme)
            {
                Margin      = theme.ButtonSpacing,
                ToolTipText = "Apply operation and make permanent".Localize(),
                Enabled     = scene.SelectedItem?.CanApply == true
            };

            applyButton.Click += (s, e) =>
            {
                this.item.Apply(view3DWidget.Scene.UndoBuffer);
                scene.SelectedItem = null;
            };
            scene.SelectionChanged += (s, e) => applyButton.Enabled = scene.SelectedItem?.CanApply == true;
            toolbar.AddChild(applyButton);

            // put in a remove button
            var removeButton = new IconButton(AggContext.StaticData.LoadIcon("close.png", 16, 16, theme.InvertIcons), theme)
            {
                Margin      = theme.ButtonSpacing,
                ToolTipText = "Remove operation from parts".Localize()
            };

            removeButton.Click += (s, e) =>
            {
                var rootSelection = scene.SelectedItemRoot;

                item.Remove(view3DWidget.Scene.UndoBuffer);

                scene.SelectedItem = null;

                if (item != rootSelection)
                {
                    scene.SelectedItem = rootSelection;
                }
            };
            toolbar.AddChild(removeButton);

            var overflowButton = new OverflowBar.OverflowMenuButton(theme);

            overflowButton.Enabled  = scene.SelectedItem != null;
            scene.SelectionChanged += (s, e) => overflowButton.Enabled = scene.SelectedItem != null;

            overflowButton.PopupBorderColor    = ApplicationController.Instance.MenuTheme.GetBorderColor(120);
            overflowButton.DynamicPopupContent = () =>
            {
                return(ApplicationController.Instance.GetActionMenuForSceneItem(item, sceneContext.Scene));
            };
            toolbar.AddChild(overflowButton);

            editorPanel = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit,
                Name    = "editorPanel",
                Padding = new BorderDouble(right: theme.DefaultContainerPadding + 1)
            };

            // Wrap editorPanel with scrollable container
            var scrollableWidget = new ScrollableWidget(true)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch
            };

            scrollableWidget.AddChild(editorPanel);
            scrollableWidget.ScrollArea.HAnchor = HAnchor.Stretch;
            scrollableWidget.Padding            = new BorderDouble(right: theme.DefaultContainerPadding * .8);

            editorSectionWidget = new ResizableSectionWidget("Editor", sceneContext.ViewState.SelectedObjectEditorHeight, scrollableWidget, theme, serializationKey: UserSettingsKey.EditorPanelExpanded, rightAlignedContent: toolbar, defaultExpansion: true)
            {
                VAnchor = VAnchor.Fit,
            };
            editorSectionWidget.Resized += (s, e) =>
            {
                sceneContext.ViewState.SelectedObjectEditorHeight = editorSectionWidget.ResizeContainer.Height;
            };

            int topBottom = theme.DefaultContainerPadding / 2;

            editorSectionWidget.ResizeContainer.Padding = new BorderDouble(left: theme.DefaultContainerPadding, top: topBottom, bottom: topBottom + editorSectionWidget.ResizeContainer.SplitterHeight);

            this.ContentPanel.AddChild(editorSectionWidget);

            var colorSection = new SectionWidget(
                "Color".Localize(),
                new ColorSwatchSelector(scene, theme, buttonSize: 16, buttonSpacing: new BorderDouble(1, 1, 0, 0))
            {
                Margin = new BorderDouble(left: 10)
            },
                theme,
                serializationKey: UserSettingsKey.ColorPanelExpanded)
            {
                Name = "Color Panel",
            };

            this.ContentPanel.AddChild(colorSection);

            var materialsSection = new SectionWidget("Materials".Localize(), new MaterialControls(scene, theme), theme, serializationKey: UserSettingsKey.MaterialsPanelExpanded)
            {
                Name = "Materials Panel",
            };

            this.ContentPanel.AddChild(materialsSection);

            // Enforce panel padding in sidebar
            foreach (var sectionWidget in this.ContentPanel.Children <SectionWidget>())
            {
                // Special case for editorResizeWrapper due to ResizeContainer
                if (sectionWidget is ResizableSectionWidget resizableSectionWidget)
                {
                    // Apply padding to ResizeContainer not wrapper
                    //resizableSectionWidget.ResizeContainer.Padding = new BorderDouble(10, 10, 10, 0);
                }
                else
                {
                    sectionWidget.ContentPanel.Padding   = new BorderDouble(10, 10, 10, 0);
                    sectionWidget.ExpandableWhenDisabled = true;
                    sectionWidget.Enabled = false;
                }
            }
        }
        public PartTabPage(PrinterConfig printer, BedConfig sceneContext, ThemeConfig theme, string tabTitle)
            : base(tabTitle)
        {
            this.sceneContext    = sceneContext;
            this.theme           = theme;
            this.BackgroundColor = theme.ActiveTabColor;
            this.Padding         = 0;
            this.printer         = printer;

            bool isPrinterType = this is PrinterTabPage;

            viewControls3D = new ViewControls3D(sceneContext, theme, sceneContext.Scene.UndoBuffer, isPrinterType)
            {
                //BackgroundColor = new Color(0, 0, 0, theme.OverlayAlpha),
                VAnchor = VAnchor.Top | VAnchor.Fit,
                HAnchor = HAnchor.Left | HAnchor.Stretch,
                Visible = true,
            };
            viewControls3D.ResetView += (sender, e) =>
            {
                if (view3DWidget.Visible)
                {
                    this.view3DWidget.ResetView();
                }
            };
            viewControls3D.ExtendOverflowMenu  = this.GetViewControls3DOverflowMenu;
            viewControls3D.OverflowButton.Name = "View3D Overflow Menu";

            // The 3D model view
            view3DWidget = new View3DWidget(
                printer,
                sceneContext,
                View3DWidget.AutoRotate.Disabled,
                viewControls3D,
                theme,
                this,
                editorType: (isPrinterType) ? MeshViewerWidget.EditorType.Printer : MeshViewerWidget.EditorType.Part);

            viewControls3D.SetView3DWidget(view3DWidget);

            this.AddChild(topToBottom = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch
            });

            topToBottom.AddChild(leftToRight = new FlowLayoutWidget()
            {
                Name    = "View3DContainerParent",
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch
            });

            view3DContainer = new GuiWidget()
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch
            };

            var toolbarAndView3DWidget = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch
            };

            toolbarAndView3DWidget.AddChild(viewControls3D);
            toolbarAndView3DWidget.AddChild(view3DWidget);
            view3DContainer.AddChild(toolbarAndView3DWidget);

            leftToRight.AddChild(view3DContainer);

            view3DWidget.BackgroundColor = ActiveTheme.Instance.TertiaryBackgroundColor;

            if (sceneContext.World.RotationMatrix == Matrix4X4.Identity)
            {
                this.view3DWidget.ResetView();
            }

            this.AnchorAll();
        }