Example #1
0
 protected override void ComposeTree(TreeComposer composer)
 {
     composer.Element("editor-container", body: () =>
     {
         composer.Element("editor", capture: element => this.editorElement = element);
     });
 }
 public static void Row(TreeComposer composer, Action left = null, Action right = null)
 {
     composer.Element("actions-row", body: () =>
     {
         composer.Element("left-actions", body: left);
         composer.Element("right-actions", body: right);
     });
 }
Example #3
0
        protected override void ComposeTree(TreeComposer composer)
        {
            if (!this.IsVisible)
            {
                return;
            }

            composer.Element(
                name: "graphics-display",
                attributes: new Dictionary <string, string>
            {
                { "tabindex", "0" },     // required to receive focus
            },
                styles: new Dictionary <string, string>
            {
                { "cursor", this.IsMouseVisible ? "initial" : "none" }
            },
                body: () =>
            {
                if (!string.IsNullOrEmpty(this.Title))
                {
                    composer.Element(
                        name: "title",
                        body: () => composer.Text(this.Title));
                }
                composer.Element(
                    name: "svg",
                    capture: element => this.RenderArea = element,
                    attributes: new Dictionary <string, string>
                {
                    { "height", "100%" },
                    { "width", "100%" },
                },
                    events: new TreeComposer.Events
                {
                    OnMouseDown = args => GraphicsDisplayStore.NotifyMouseDown(args.ClientX, args.ClientY, GetMouseButton(args.Button)),
                    OnMouseUp   = args => GraphicsDisplayStore.NotifyMouseUp(args.ClientX, args.ClientY, GetMouseButton(args.Button)),
                    OnMouseMove = args => GraphicsDisplayStore.NotifyMouseMove(args.ClientX, args.ClientY),
                },
                    body: () =>
                {
                    if (!this.Libraries.IsDefault())
                    {
                        this.Libraries.ImageList.EmbedImages(composer);
                        this.Libraries.GraphicsWindow.ComposeTree(composer);
                        this.Libraries.Shapes.ComposeTree(composer);
                        this.Libraries.Turtle.ComposeTree(composer);
                    }
                });

                if (!this.Libraries.IsDefault())
                {
                    this.Libraries.Controls.ComposeTree(composer);
                }
            });
        }
        public static void DisabledAction(TreeComposer composer, string name, string title, string message)
        {
            composer.Element("disabled-action-container", body: () =>
            {
                composer.Element("action", body: () =>
                {
                    composer.Element("icon-" + name);
                    composer.Text(title);
                });

                composer.Element("disabled-message", body: () => composer.Text(message));
            });
        }
 public static void Action(TreeComposer composer, string name, string title, Func <Task> onClick)
 {
     composer.Element(
         name: "action",
         events: new TreeComposer.Events
     {
         OnClickAsync = args => onClick()
     },
         body: () =>
     {
         composer.Element("icon-" + name);
         composer.Text(title);
     });
 }
Example #6
0
 protected override void ComposeBody(TreeComposer composer)
 {
     composer.Element("run-page", body: () =>
     {
         EngineDisplay.Inject(composer, this.engine);
     });
 }
 internal void EmbedImages(TreeComposer composer)
 {
     composer.Element(name: "defs", body: () =>
     {
         foreach (var pair in this.images)
         {
             composer.Element("image", attributes: new Dictionary <string, string>
             {
                 { "id", pair.Key },
                 { "width", pair.Value.Width.ToString(CultureInfo.CurrentCulture) },
                 { "height", pair.Value.Height.ToString(CultureInfo.CurrentCulture) },
                 { "href", $"data:image/image;base64,{pair.Value.Base64Contents}" }
             });
         }
     });
 }
Example #8
0
        public override void ComposeTree(TreeComposer composer)
        {
            var attributes = new Dictionary <string, string>
            {
                { "x", this.X.ToString(CultureInfo.CurrentCulture) },
                { "y", this.Y.ToString(CultureInfo.CurrentCulture) },
                { "dy", this.Styles.FontSize.ToString(CultureInfo.CurrentCulture) }
            };

            if (this.Width.HasValue)
            {
                attributes.Add("textLength", this.Width.Value.ToString(CultureInfo.CurrentCulture));
            }

            composer.Element(
                name: "text",
                styles: new Dictionary <string, string>
            {
                { "fill", this.Styles.BrushColor },
                { "font-weight", this.Styles.FontBold ? "bold" : "normal" },
                { "font-style", this.Styles.FontItalic ? "italic" : "normal" },
                { "font-family", $@"""{this.Styles.FontName}""" },
                { "font-size", $"{this.Styles.FontSize}px" },
                { "pointer-events", "none" }
            },
                attributes: attributes,
                body: () => composer.Text(this.Text));
        }
Example #9
0
 public static void FontAwesome(TreeComposer composer, string iconName)
 {
     composer.Element(name: "font-awesome-icon", attributes: new Dictionary <string, string>
     {
         { "class", $"fas fa-{iconName}" }
     });
 }
Example #10
0
        protected override void ComposeTree(TreeComposer composer)
        {
            composer.Element(
                name: "text-display",
                capture: element => this.textDisplayRef = element,
                styles: new Dictionary <string, string>
            {
                { "background-color", this.backgroundColor }
            },
                attributes: new Dictionary <string, string>
            {
                { "tabindex", "0" },     // required to receive focus
            },
                events: new TreeComposer.Events
            {
                OnKeyDownAsync = args => this.AcceptInput(args.Key)
            },
                body: () =>
            {
                if (!string.IsNullOrEmpty(this.Title))
                {
                    composer.Element(
                        name: "title",
                        body: () => composer.Text(this.Title));
                }
                foreach (var chunk in this.outputChunks)
                {
                    composer.Element(
                        name: "span",
                        body: () => composer.Text(chunk.Text),
                        styles: new Dictionary <string, string>
                    {
                        { "color", chunk.HexColor }
                    });

                    if (chunk.AppendNewLine)
                    {
                        composer.Element("br");
                    }
                }

                composer.Element("input-field", capture: element => this.inputFieldRef = element, body: () =>
                {
                    if (this.mode != AcceptedInputMode.None)
                    {
                        composer.Element("span", body: () => composer.Text(this.inputBuffer));
                        composer.Element(name: "span", body: () =>
                        {
                            composer.Element("cursor", body: () =>
                            {
                                composer.Markup("&#x2588;");
                            });
                        });
                    }
                });
            });
        }
Example #11
0
        protected override void ComposeBody(TreeComposer composer)
        {
            composer.Element("edit-page", body: () =>
            {
                LibraryExplorer.Inject(composer);

                composer.Element("main-space", body: () =>
                {
                    composer.Element("editor-space", body: () =>
                    {
                        MonacoEditor.Inject(composer, isReadOnly: false);
                    });

                    ErrorsSpace.Inject(composer);
                });
            });
        }
Example #12
0
        protected override void ComposeBody(TreeComposer composer)
        {
            composer.Element("debug-page", body: () =>
            {
                MemoryExplorer.Inject(composer, this.engine);

                composer.Element("main-space", body: () =>
                {
                    composer.Element("editor-space", body: () =>
                    {
                        MonacoEditor.Inject(composer, isReadOnly: true);
                    });

                    EngineDisplay.Inject(composer, this.engine);
                });
            });
        }
        private void ComposeHeader(TreeComposer composer)
        {
            composer.Element("header-area", body: () =>
            {
                composer.Element(
                    name: "logo-area",
                    events: new TreeComposer.Events
                {
                    OnClick = args => this.isExpanded = !this.isExpanded
                },
                    body: () =>
                {
                    composer.Element("logo");
                });

                composer.Element("empty-scroll-area");

                if (this.isExpanded)
                {
                    composer.Element("title-area", body: () => composer.Text(EditorResources.MemoryExplorer_Title));
                    composer.Element(
                        name: "minimize-button",
                        events: new TreeComposer.Events
                    {
                        OnClick = args => this.isExpanded = false
                    },
                        body: () =>
                    {
                        composer.Element("angle-left");
                    });
                }
            });
        }
Example #14
0
 public override void ComposeTree(ControlsLibrary library, TreeComposer composer)
 {
     composer.Element(
         name: "button",
         body: () => composer.Text(this.Caption),
         events: new TreeComposer.Events
     {
         OnClick = args => library.NotifyButtonClicked(this.Name)
     },
         styles: this.Styles);
 }
 public override void ComposeTree(TreeComposer composer)
 {
     composer.Element(
         name: "image",
         attributes: new Dictionary <string, string>
     {
         { "href", $"Turtle.svg" },
         /* width and height attributes required on Firefox */
         { "width", Width.ToString(CultureInfo.CurrentCulture) },
         { "height", Height.ToString(CultureInfo.CurrentCulture) }
     });
 }
 public override void ComposeTree(TreeComposer composer)
 {
     composer.Element(
         name: "image",
         attributes: new Dictionary <string, string>
     {
         { "href", this.Name },
         { "x", this.X.ToString(CultureInfo.CurrentCulture) },
         { "y", this.Y.ToString(CultureInfo.CurrentCulture) },
         { "transform", $"scale({this.ScaleX}, {this.ScaleY})" }
     });
 }
        protected override void ComposeTree(TreeComposer composer)
        {
            composer.Element("memory-explorer", body: () =>
            {
                composer.Element(
                    name: this.isExpanded ? "content-area-expanded" : "content-area-contracted",
                    body: () =>
                {
                    this.ComposeHeader(composer);

                    composer.Element("member-area", body: () =>
                    {
                        if (this.isExpanded)
                        {
                            this.ComposeVariables(composer);
                            this.ComposeCallStack(composer);
                        }
                    });
                });
            });
        }
 protected override void ComposeTree(TreeComposer composer)
 {
     composer.Element("library-explorer", body: () =>
     {
         composer.Element("navigation-area", body: () =>
         {
             composer.Element(
                 name: "logo-area",
                 events: new TreeComposer.Events
             {
                 OnClick = args =>
                 {
                     if (this.selectedLibrary.IsDefault())
                     {
                         this.selectedLibrary = Libraries.Types.Values.First();
                     }
                     else
                     {
                         this.selectedLibrary = default;
                     }
                 }
             },
        private void ComposeOnlyIfNotRunning(TreeComposer composer, bool showEvenIfTerminated, Action body)
        {
            switch (this.Engine.State)
            {
            case ExecutionState.BlockedOnNumberInput:
            case ExecutionState.BlockedOnStringInput:
            case ExecutionState.Paused:
            {
                body();
                break;
            }

            case ExecutionState.Running:
            {
                composer.Element("running-block", body: () =>
                    {
                        composer.Element("icon-container", body: () => composer.Element("program-running-icon"));
                        composer.Element("text-container", body: () => composer.Text(EditorResources.MemoryExplorer_ProgramRunning));
                    });

                break;
            }

            case ExecutionState.Terminated:
            {
                if (showEvenIfTerminated)
                {
                    body();
                }
                else
                {
                    composer.Element("running-block", body: () =>
                        {
                            composer.Element("icon-container", body: () => composer.Element("program-ended-icon"));
                            composer.Element("text-container", body: () => composer.Text(EditorResources.MemoryExplorer_ProgramEnded));
                        });
                }

                break;
            }

            default:
            {
                throw ExceptionUtilities.UnexpectedValue(this.Engine.State);
            }
            }
        }
Example #20
0
 public override void ComposeTree(TreeComposer composer)
 {
     composer.Element(
         name: "polygon",
         styles: new Dictionary <string, string>
     {
         { "fill", this.Styles.BrushColor },
         { "stroke", this.Styles.PenColor },
         { "stroke-width", $"{this.Styles.PenWidth}px" },
     },
         attributes: new Dictionary <string, string>
     {
         { "points", string.Join(",", this.X1, this.Y1, this.X2, this.Y2, this.X3, this.Y3) }
     });
 }
        private Action AttachTranslation(Action body, TreeComposer composer)
        {
            if (this.TranslateX == 0 && this.TranslateY == 0 && !this.TranslationAnimation.HasValue)
            {
                return(body);
            }

            return(() =>
            {
                composer.Element(
                    name: "g",
                    attributes: new Dictionary <string, string>
                {
                    { "transform", this.TranslationAnimation.HasValue ? string.Empty : $"translate({this.TranslateX}, {this.TranslateY})" },
                },
                    styles: new Dictionary <string, string>
                {
                    { "transform-origin", "0 0" },
                    { "transform-box", "view-box" },
                },
                    body: () =>
                {
                    if (this.TranslationAnimation.HasValue)
                    {
                        (decimal x, decimal y, decimal duration, double start) = this.TranslationAnimation.Value;

                        composer.Element(
                            name: "animateTransform",
                            attributes: new Dictionary <string, string>
                        {
                            { "attributeName", "transform" },
                            { "type", "translate" },
                            { "from", $"{this.TranslateX} {this.TranslateY}" },
                            { "to", $"{x} {y}" },
                            { "begin", $"{start}s" },
                            { "dur", $"{duration / 1000}s" },
                            { "fill", "freeze" },
                            { "additive", "sum" },
                        });
                    }

                    body();
                });
            });
        }
Example #22
0
        private Action AttachRotation(Action body, TreeComposer composer)
        {
            if (this.Angle == 0 && !this.AngleAnimation.HasValue)
            {
                return(body);
            }

            return(() =>
            {
                composer.Element(
                    name: "g",
                    attributes: new Dictionary <string, string>
                {
                    { "transform", this.AngleAnimation.HasValue ? string.Empty : $"rotate({this.Angle}, {this.Width / 2}, {this.Height / 2})" },
                },
                    styles: new Dictionary <string, string>
                {
                    { "transform-origin", "center center" },
                    { "transform-box", "fill-box" },
                },
                    body: () =>
                {
                    if (this.AngleAnimation.HasValue)
                    {
                        (decimal angle, decimal duration, double start) = this.AngleAnimation.Value;

                        composer.Element(
                            name: "animateTransform",
                            attributes: new Dictionary <string, string>
                        {
                            { "attributeName", "transform" },
                            { "type", "rotate" },
                            { "from", this.Angle.ToString(CultureInfo.CurrentCulture) },
                            { "to", angle.ToString(CultureInfo.CurrentCulture) },
                            { "begin", $"{start}s" },
                            { "dur", $"{duration / 1000}s" },
                            { "fill", "freeze" },
                            { "additive", "sum" },
                        });
                    }

                    body();
                });
            });
        }
        private Action AttachOpacity(Action body, TreeComposer composer)
        {
            if (this.Opacity == 100)
            {
                return(body);
            }

            return(() =>
            {
                composer.Element(
                    name: "g",
                    attributes: new Dictionary <string, string>
                {
                    { "opacity", (this.Opacity / 100).ToString(CultureInfo.CurrentCulture) },
                },
                    body: body);
            });
        }
 private Action AttachScale(Action body, TreeComposer composer)
 {
     return(() =>
     {
         composer.Element(
             name: "g",
             attributes: new Dictionary <string, string>
         {
             { "transform", $"scale({this.ScaleX}, {this.ScaleY})" },
         },
             styles: new Dictionary <string, string>
         {
             { "transform-origin", "center center" },
             { "transform-box", "fill-box" }
         },
             body: body);
     });
 }
Example #25
0
        private Action AttachScale(Action body, TreeComposer composer)
        {
            if (this.ScaleX == 1 && this.ScaleY == 1)
            {
                return(body);
            }

            return(() =>
            {
                composer.Element(
                    name: "g",
                    attributes: new Dictionary <string, string>
                {
                    { "transform", $"scale({this.ScaleX}, {this.ScaleY})" },
                },
                    body: body);
            });
        }
 public override void ComposeTree(TreeComposer composer)
 {
     composer.Element(
         name: "ellipse",
         styles: new Dictionary <string, string>
     {
         { "fill", this.Styles.BrushColor },
         { "stroke", this.Styles.PenColor },
         { "stroke-width", $"{this.Styles.PenWidth}px" },
     },
         attributes: new Dictionary <string, string>
     {
         { "cx", (this.X - (this.Width / 2)).ToString(CultureInfo.CurrentCulture) },
         { "cy", (this.Y - (this.Height / 2)).ToString(CultureInfo.CurrentCulture) },
         { "rx", (this.Width / 2).ToString(CultureInfo.CurrentCulture) },
         { "ry", (this.Height / 2).ToString(CultureInfo.CurrentCulture) },
     });
 }
 public override void ComposeTree(ControlsLibrary library, TreeComposer composer)
 {
     composer.Element(
         name: "textarea",
         styles: this.Styles,
         events: new TreeComposer.Events
     {
         OnInput = args =>
         {
             this.Text = args.Value.ToString();
             library.NotifyTextTyped(this.Name);
         }
     },
         attributes: new Dictionary <string, string>()
     {
         { "value", this.Text },
     });
 }
 public override void ComposeTree(TreeComposer composer)
 {
     composer.Element(
         name: "rect",
         styles: new Dictionary <string, string>
     {
         { "fill", this.Styles.BrushColor },
         { "stroke", this.Styles.PenColor },
         { "stroke-width", $"{this.Styles.PenWidth}px" },
     },
         attributes: new Dictionary <string, string>
     {
         { "x", this.X.ToString(CultureInfo.CurrentCulture) },
         { "y", this.Y.ToString(CultureInfo.CurrentCulture) },
         { "width", this.Width.ToString(CultureInfo.CurrentCulture) },
         { "height", this.Height.ToString(CultureInfo.CurrentCulture) },
     });
 }
Example #29
0
        protected sealed override void ComposeTree(TreeComposer composer)
        {
            composer.Element("main-layout", body: () =>
            {
                composer.Element("header-row", body: () =>
                {
                    composer.Element("logo-area", body: () =>
                    {
                        composer.Element(
                            name: "logo",
                            events: new TreeComposer.Events
                        {
                            OnClickAsync = args => OpenExtrernalLink("http://www.smallbasic.com")
                        });
                    });

                    composer.Element("header-links", body: () =>
                    {
                        foreach (var pair in HeaderLinks)
                        {
                            composer.Element(
                                name: "header-link",
                                events: new TreeComposer.Events
                            {
                                OnClickAsync = args => OpenExtrernalLink(pair.Value)
                            },
                                body: () =>
                            {
                                composer.Text(pair.Key);
                            });
                        }
                    });
                });

                Actions.Row(composer, left: () => this.ComposeLeftActions(composer), right: () => this.ComposeRightActions(composer));

                composer.Element("page-contents", body: () =>
                {
                    this.ComposeBody(composer);
                });
            });
        }
        protected override void ComposeTree(TreeComposer composer)
        {
            composer.Element(
                name: "engine-display",
                attributes: new Dictionary <string, string>
            {
                // Important to prevent the right-click menu
                { "oncontextmenu", "return false;" }
            },
                body: () =>
            {
                if (CompilationStore.Compilation.Analysis.UsesTextWindow)
                {
                    TextDisplay.Inject(composer);
                }

                if (CompilationStore.Compilation.Analysis.UsesGraphicsWindow)
                {
                    GraphicsDisplay.Inject(composer, this.Engine.Libraries);
                }
            });
        }