private Microsoft.Msagl.Drawing.Graph CreateGraph(
            AdminShellPackageEnv env,
            AdminShell.Submodel sm,
            GenericBomCreatorOptions options)
        {
            // access
            if (env == null || sm == null || options == null)
            {
                return(null);
            }

            //create a graph object
            Microsoft.Msagl.Drawing.Graph graph = new Microsoft.Msagl.Drawing.Graph("BOM-graph");

#if FALSE
            //create the graph content
            graph.AddEdge("A", "B");
            var e1 = graph.AddEdge("B", "C");
            // e1.LabelText = "Dumpf!";
            e1.LabelText = "hbhbjhbjhb";
            // e1.Label = new Microsoft.Msagl.Drawing.Label("Dumpf!!");
            graph.AddEdge("A", "C").Attr.Color = Microsoft.Msagl.Drawing.Color.Green;
            graph.FindNode("A").Attr.FillColor = Microsoft.Msagl.Drawing.Color.Magenta;
            graph.FindNode("B").Attr.FillColor = Microsoft.Msagl.Drawing.Color.MistyRose;
            Microsoft.Msagl.Drawing.Node c = graph.FindNode("C");
            graph.FindNode("B").LabelText = "HalliHallo";
            c.Attr.FillColor = Microsoft.Msagl.Drawing.Color.PaleGreen;
            c.Attr.Shape     = Microsoft.Msagl.Drawing.Shape.Diamond;
            c.Label.FontSize = 28;
#else
            var creator = new GenericBomCreator(
                env?.AasEnv,
                _bomRecords,
                options);

            using (var tw = new StreamWriter("bomgraph.log"))
            {
                creator.RecurseOnLayout(1, graph, null, sm.submodelElements, 1, tw);
                creator.RecurseOnLayout(2, graph, null, sm.submodelElements, 1, tw);
                creator.RecurseOnLayout(3, graph, null, sm.submodelElements, 1, tw);
            }

            // make default or (already) preferred settings
            var settings = GivePresetSettings(options.LayoutIndex);
            if (this.preferredPresetIndex != null && this.preferredPresetIndex.ContainsKey(sm))
            {
                settings = GivePresetSettings(this.preferredPresetIndex[sm]);
            }
            if (settings != null)
            {
                graph.LayoutAlgorithmSettings = settings;
            }
#endif
            return(graph);
        }
 public GenericBomCreator(
     AdminShell.AdministrationShellEnv env,
     BomStructureOptionsRecordList bomRecords,
     GenericBomCreatorOptions options)
 {
     _env        = env;
     _bomRecords = bomRecords;
     _options    = options;
     _refStore   = new AasReferableStore();
     _refStore.Index(env);
 }
        public object FillWithWpfControls(
            BomStructureOptions bomOptions,
            object opackage, object osm, object masterDockPanel)
        {
            // access
            _package    = opackage as AdminShellPackageEnv;
            _submodel   = osm as AdminShell.Submodel;
            _bomOptions = bomOptions;
            var master = masterDockPanel as DockPanel;

            if (_bomOptions == null || _package == null || _submodel == null || master == null)
            {
                return(null);
            }

            // set of records helping layouting
            _bomRecords = new BomStructureOptionsRecordList(_bomOptions?.MatchingRecords(_submodel.semanticId));

            // clear some other members (GenericBomControl is not allways created new)
            _creatorOptions = new GenericBomCreatorOptions();

            // apply some global options?
            foreach (var br in _bomRecords)
            {
                if (br.Layout >= 1 && br.Layout <= PresetSettingNames.Length)
                {
                    _creatorOptions.LayoutIndex = br.Layout - 1;
                }
                if (br.Compact.HasValue)
                {
                    _creatorOptions.CompactLabels = br.Compact.Value;
                }
            }

            // the Submodel elements need to have parents
            _submodel.SetAllParents();

            // prepare options for fast access
            _bomOptions.Index();

            // create TOP controls
            var spTop = new StackPanel();

            spTop.Orientation = Orientation.Horizontal;
            DockPanel.SetDock(spTop, Dock.Top);
            master.Children.Add(spTop);

            var lb1 = new Label();

            lb1.Content = "Layout style: ";
            spTop.Children.Add(lb1);

            var cbli = new ComboBox();

            foreach (var psn in this.PresetSettingNames)
            {
                cbli.Items.Add(psn);
            }
            cbli.SelectedIndex     = _creatorOptions.LayoutIndex;
            cbli.SelectionChanged += CbLayoutIndex_SelectionChanged;
            spTop.Children.Add(cbli);

            var cbcomp = new CheckBox();

            cbcomp.Content = "Compact labels";
            cbcomp.Margin  = new System.Windows.Thickness(10, 0, 10, 0);
            cbcomp.VerticalContentAlignment = System.Windows.VerticalAlignment.Center;
            cbcomp.IsChecked  = _creatorOptions.CompactLabels;
            cbcomp.Checked   += CbCompactLabels_CheckedChanged;
            cbcomp.Unchecked += CbCompactLabels_CheckedChanged;
            spTop.Children.Add(cbcomp);

            // create BOTTOM controls
            var legend = GenericBomCreator.GenerateWrapLegend();

            DockPanel.SetDock(legend, Dock.Bottom);
            master.Children.Add(legend);

            // set default for very small edge label size
            Microsoft.Msagl.Drawing.Label.DefaultFontSize = 6;

            // make a Dock panel
            var dp = new DockPanel();

            dp.ClipToBounds = true;
            dp.MinWidth     = 10;
            dp.MinHeight    = 10;

            // very important: add first the panel, then add graph
            master.Children.Add(dp);

            // graph
            var graph = CreateGraph(_package, _submodel, _creatorOptions);

            // very important: first bind it, then add graph
            var viewer = new Microsoft.Msagl.WpfGraphControl.GraphViewer();

            viewer.BindToPanel(dp);
            viewer.MouseDown += Viewer_MouseDown;
            viewer.MouseMove += Viewer_MouseMove;
            viewer.MouseUp   += Viewer_MouseUp;
            viewer.ObjectUnderMouseCursorChanged += Viewer_ObjectUnderMouseCursorChanged;
            viewer.Graph = graph;

            // make it re-callable
            theGraph     = graph;
            theViewer    = viewer;
            theReferable = _submodel;

            // return viewer for advanced manilulation
            return(viewer);
        }