Пример #1
0
        /// <summary>
        /// Size the SVG image to completely fill its container. Call this when the view
        /// actually changes sizes (e.g. on a window resize/device orientation change).
        /// See Blockly.resizeSvgContents to resize the workspace when the contents
        /// change (e.g. when a block is added or removed).
        /// Record the height/width of the SVG image.
        /// </summary>
        /// <param name="workspace">Any workspace in the SVG.</param>
        public static void svgResize(WorkspaceSvg workspace)
        {
            var mainWorkspace = workspace;

            while (mainWorkspace.options.parentWorkspace != null)
            {
                mainWorkspace = (WorkspaceSvg)mainWorkspace.options.parentWorkspace;
            }
            var svg = mainWorkspace.getParentSvg();
            var div = (HTMLDivElement)svg.ParentNode;

            if (div == null)
            {
                // Workspace deleted, or something.
                return;
            }
            var width  = div.OffsetWidth;
            var height = div.OffsetHeight;

            if ((double?)svg["cachedWidth_"] != width)
            {
                svg.SetAttribute("width", width + "px");
                svg["cachedWidth_"] = width;
            }
            if ((double?)svg["cachedHeight_"] != height)
            {
                svg.SetAttribute("height", height + "px");
                svg["cachedHeight_"] = height;
            }
            mainWorkspace.resize();
        }
Пример #2
0
        /// <summary>
        /// Bind the localStorage backup function to the unload event.
        /// </summary>
        /// <param name="opt_workspace">Workspace.</param>
        public static void backupOnUnload(WorkspaceSvg opt_workspace = null)
        {
            var workspace = opt_workspace ?? Blockly.Core.getMainWorkspace();

            Window.AddEventListener("unload",
                                    new Action(() => { BlocklyStorage.backupBlocks_(workspace); }), false);
        }
Пример #3
0
        /// <summary>
        /// Return the absolute coordinates of the top-left corner of this element,
        /// scales that after canvas SVG element, if it's a descendant.
        /// The origin (0,0) is the top-left corner of the Blockly SVG.
        /// </summary>
        /// <param name="element">Element to find the coordinates of.</param>
        /// <param name="workspace">Element must be in this workspace.</param>
        /// <returns>Object with .x and .y properties.</returns>
        internal static goog.math.Coordinate getSvgXY_(SVGElement element,
                                                       WorkspaceSvg workspace)
        {
            var x     = 0.0;
            var y     = 0.0;
            var scale = 1.0;

            if (goog.dom.contains(workspace.getCanvas(), element) ||
                goog.dom.contains(workspace.getBubbleCanvas(), element))
            {
                // Before the SVG canvas, scale the coordinates.
                scale = workspace.scale;
            }
            do
            {
                // Loop through this block and every parent.
                var xy = Core.getRelativeXY_(element);
                if (element == workspace.getCanvas() ||
                    element == workspace.getBubbleCanvas())
                {
                    // After the SVG canvas, don't scale the coordinates.
                    scale = 1;
                }
                x      += xy.x * scale;
                y      += xy.y * scale;
                element = element.ParentNode as SVGElement;
            } while (element != null && element != workspace.getParentSvg());
            return(new goog.math.Coordinate(x, y));
        }
Пример #4
0
        /// <summary>
        /// Initialize Blockly with various handlers.
        /// </summary>
        /// <param name="mainWorkspace">Newly created main workspace.</param>
        private static void init_(WorkspaceSvg mainWorkspace)
        {
            var options = mainWorkspace.options;
            var svg     = mainWorkspace.getParentSvg();

            // Supress the browser's context menu.
            Core.bindEventWithChecks_(svg, "contextmenu", null,
                                      new Action <Event>((e) => {
                if (!Core.isTargetInput_(e))
                {
                    e.PreventDefault();
                }
            }));

            var workspaceResizeHandler = Core.bindEventWithChecks_(new Node(Window.Instance.instance), "resize",
                                                                   null,
                                                                   new Action <Event>((e) => {
                Core.hideChaff(true);
                Core.svgResize(mainWorkspace);
            }));

            mainWorkspace.setResizeHandlerWrapper(workspaceResizeHandler);

            Core.inject_bindDocumentEvents_();

            if (options.languageTree != null)
            {
                if (mainWorkspace.toolbox_ != null)
                {
                    mainWorkspace.toolbox_.init(/*mainWorkspace*/);
                }
                else if (mainWorkspace.flyout_ != null)
                {
                    // Build a fixed flyout with the root blocks.
                    mainWorkspace.flyout_.init(mainWorkspace);
                    mainWorkspace.flyout_.show(options.languageTree.ChildNodes);
                    mainWorkspace.flyout_.scrollToStart();
                    // Translate the workspace sideways to avoid the fixed flyout.
                    mainWorkspace.scrollX = mainWorkspace.flyout_.width_;
                    if (options.toolboxPosition == Core.TOOLBOX_AT_RIGHT)
                    {
                        mainWorkspace.scrollX *= -1;
                    }
                    mainWorkspace.translate(mainWorkspace.scrollX, 0);
                }
            }

            if (options.hasScrollbars)
            {
                mainWorkspace.scrollbar = new ScrollbarPair(mainWorkspace);
                mainWorkspace.scrollbar.resize();
            }

            // Load the sounds.
            if (options.hasSounds)
            {
                Core.inject_loadSounds_(options.pathToMedia, mainWorkspace);
            }
        }
Пример #5
0
        /// <summary>
        /// Show the inline free-text editor on top of the text.
        /// </summary>
        /// <param name="opt_quietInput">True if editor should be created without
        /// focus.Defaults to false.</param>
        public override void showEditor_(bool opt_quietInput)
        {
            this.workspace_ = (WorkspaceSvg)this.sourceBlock_.workspace;
            var quietInput = opt_quietInput || false;

            if (!quietInput && (goog.userAgent.MOBILE || goog.userAgent.ANDROID ||
                                goog.userAgent.IPAD))
            {
                // Mobile browsers have issues with in-line textareas (focus & keyboards).
                var newValue = Window.Prompt(Msg.CHANGE_VALUE_TITLE, this.text_);
                if (this.sourceBlock_ != null)
                {
                    newValue = this.callValidator(newValue);
                }
                this.setValue(newValue);
                return;
            }

            WidgetDiv.show(this, this.sourceBlock_.RTL, this.widgetDispose_());
            var div = WidgetDiv.DIV;
            // Create the input.
            var htmlInput = (HTMLInputElement)
                            goog.dom.createDom(goog.dom.TagName.INPUT, "blocklyHtmlInput");

            htmlInput.SetAttribute("spellcheck", this.spellcheck_.ToString());
            var fontSize =
                (FieldTextInput.FONTSIZE * this.workspace_.scale) + "pt";

            div.Style.FontSize       = fontSize;
            htmlInput.Style.FontSize = fontSize;
            /** @type {!HTMLInputElement} */
            FieldTextInput.htmlInput_ = htmlInput;
            div.AppendChild(htmlInput);

            htmlInput.Value        = htmlInput.DefaultValue = this.text_;
            htmlInput["oldValue_"] = null;
            this.validate_();
            this.resizeEditor_();
            if (!quietInput)
            {
                htmlInput.Focus();
                htmlInput.Select();
            }

            // Bind to keydown -- trap Enter without IME and Esc to hide.
            htmlInput["onKeyDownWrapper_"] =
                Core.bindEventWithChecks_(htmlInput, "keydown", this,
                                          new Action <KeyboardEvent>(this.onHtmlInputKeyDown_));
            // Bind to keyup -- trap Enter; resize after every keystroke.
            htmlInput["onKeyUpWrapper_"] =
                Core.bindEventWithChecks_(htmlInput, "keyup", this,
                                          new Action <Event>(this.onHtmlInputChange_));
            // Bind to keyPress -- repeatedly resize when holding down a key.
            htmlInput["onKeyPressWrapper_"] =
                Core.bindEventWithChecks_(htmlInput, "keypress", this,
                                          new Action <Event>(this.onHtmlInputChange_));
            htmlInput["onWorkspaceChangeWrapper_"] = new Action <Events.Abstract>(this.resizeEditor_);
            this.workspace_.addChangeListener((Action <Events.Abstract>)htmlInput["onWorkspaceChangeWrapper_"]);
        }
Пример #6
0
 /// <summary>
 /// Dispose of this toolbox.
 /// </summary>
 public void dispose()
 {
     this.flyout_.dispose();
     this.tree_.dispose();
     goog.dom.removeNode(this.HtmlDiv);
     this.workspace_    = null;
     this.lastCategory_ = null;
 }
Пример #7
0
        /// <summary>
        /// Save blocks to database and return a link containing key to XML.
        /// </summary>
        /// <param name="opt_workspace">Workspace.</param>
        public static void link(WorkspaceSvg opt_workspace = null)
        {
            var workspace = opt_workspace ?? Blockly.Core.getMainWorkspace();
            var xml       = Blockly.Xml.workspaceToDom(workspace);
            var data      = Blockly.Xml.domToText(xml);

            BlocklyStorage.makeRequest_("/storage", "xml", data, workspace);
        }
Пример #8
0
 public void dispose()
 {
     if (this.svgGroup_ != null)
     {
         goog.dom.removeNode(this.svgGroup_);
         this.svgGroup_ = null;
     }
     this.workspace_ = null;
 }
Пример #9
0
 /// <summary>
 /// Class for a button in the flyout.
 /// </summary>
 /// <param name="workspace">The workspace in which to place this
 /// button.</param>
 /// <param name="targetWorkspace">The flyout's target workspace.</param>
 /// <param name="text">The text to display on the button.</param>
 public FlyoutButton(WorkspaceSvg workspace, WorkspaceSvg targetWorkspace, string text,
                     string d = null, bool label = false)
 {
     this.workspace_       = workspace;
     this.targetWorkspace_ = targetWorkspace;
     this.text_            = text;
     position_             = new goog.math.Coordinate(0.0, 0.0);
     this.callback_        = Core.flyoutButtonCallbacks_[d];
     this.isLabel_         = label;
 }
Пример #10
0
 /// <summary>
 /// Backup code blocks to localStorage.
 /// </summary>
 /// <param name="workspace">Workspace.</param>
 private static void backupBlocks_(WorkspaceSvg workspace)
 {
     if (Window.LocalStorage != null)
     {
         var xml = Blockly.Xml.workspaceToDom(workspace);
         // Gets the current URL, not including the hash.
         var url = Window.Location.Href.Split('#')[0];
         Window.LocalStorage.SetItem(url, Blockly.Xml.domToText(xml));
     }
 }
Пример #11
0
 /// <summary>
 /// Dispose of this pair of scrollbars.
 /// Unlink from all DOM elements to prevent memory leaks.
 /// </summary>
 public void dispose()
 {
     goog.dom.removeNode(this.corner_);
     this.corner_         = null;
     this.workspace_      = null;
     this.oldHostMetrics_ = null;
     this.hScroll.dispose();
     this.hScroll = null;
     this.vScroll.dispose();
     this.vScroll = null;
 }
Пример #12
0
        /// <summary>
        /// Initialize a set of connection DBs for a specified workspace.
        /// </summary>
        /// <param name="workspace">The workspace this DB is for.</param>
        public static void init(WorkspaceSvg workspace)
        {
            // Create four databases, one for each connection type.
            var dbList = new ConnectionDB[5];

            dbList[Core.INPUT_VALUE]        = new ConnectionDB();
            dbList[Core.OUTPUT_VALUE]       = new ConnectionDB();
            dbList[Core.NEXT_STATEMENT]     = new ConnectionDB();
            dbList[Core.PREVIOUS_STATEMENT] = new ConnectionDB();
            workspace.connectionDBList      = dbList;
        }
Пример #13
0
        /// <summary>
        /// Restore code blocks from localStorage.
        /// </summary>
        /// <param name="opt_workspace">Workspace.</param>
        public static void restoreBlocks(WorkspaceSvg opt_workspace = null)
        {
            var url = Window.Location.Href.Split('#')[0];

            if (Window.LocalStorage != null && Window.LocalStorage[url] != null)
            {
                var workspace = opt_workspace ?? Blockly.Core.getMainWorkspace();
                var xml       = Blockly.Xml.textToDom((string)Window.LocalStorage[url]);
                Blockly.Xml.domToWorkspace(xml, workspace);
            }
        }
Пример #14
0
 /// <summary>
 /// Dispose of this trash can.
 /// Unlink from all DOM elements to prevent memory leaks.
 /// </summary>
 public void dispose()
 {
     if (this.svgGroup_ != null)
     {
         goog.dom.removeNode(this.svgGroup_);
         this.svgGroup_ = null;
     }
     this.svgLid_    = null;
     this.workspace_ = null;
     goog.Timer.clear(this.lidTask_);
 }
Пример #15
0
 /// <summary>
 /// Dispose of this bubble.
 /// </summary>
 public void dispose()
 {
     Bubble.unbindDragEvents_();
     // Dispose of and unlink the bubble.
     goog.dom.removeNode(this.bubbleGroup_);
     this.bubbleGroup_ = null;
     this.bubbleArrow_ = null;
     this.bubbleBack_  = null;
     this.resizeGroup_ = null;
     this.workspace_   = null;
     this.content_     = null;
     this.shape_       = null;
 }
Пример #16
0
 public ScrollbarPair(WorkspaceSvg workspace)
 {
     this.workspace_ = workspace;
     this.hScroll    = new Scrollbar(workspace, true, true);
     this.vScroll    = new Scrollbar(workspace, false, true);
     this.corner_    = Core.createSvgElement("rect", new Dictionary <string, object>()
     {
         { "height", Scrollbar.scrollbarThickness },
         { "width", Scrollbar.scrollbarThickness },
         { "class", "blocklyScrollbarBackground" }
     }, null);
     Scrollbar.insertAfter_(this.corner_, workspace.getBubbleCanvas());
 }
Пример #17
0
        /// <summary>
        /// Dispose of this scrollbar.
        /// Unlink from all DOM elements to prevent memory leaks.
        /// </summary>
        public void dispose()
        {
            this.cleanUp_();
            Core.unbindEvent_(this.onMouseDownBarWrapper_);
            this.onMouseDownBarWrapper_ = null;
            Core.unbindEvent_(this.onMouseDownHandleWrapper_);
            this.onMouseDownHandleWrapper_ = null;

            goog.dom.removeNode(this.svgGroup_);
            this.svgGroup_      = null;
            this.svgBackground_ = null;
            this.svgHandle_     = null;
            this.workspace_     = null;
        }
Пример #18
0
        /// <summary>
        /// Duplicate this block and its children.
        /// </summary>
        /// <param name="block">Block to be copied.</param>
        internal static void duplicate_(Block block)
        {
            // Save the clipboard.
            var clipboardXml    = Core.clipboardXml_;
            var clipboardSource = Core.clipboardSource_;

            // Create a duplicate via a copy/paste operation.
            Core.copy_(block);
            ((WorkspaceSvg)block.workspace).paste(Core.clipboardXml_);

            // Restore the clipboard.
            Core.clipboardXml_    = clipboardXml;
            Core.clipboardSource_ = clipboardSource;
        }
Пример #19
0
        /// <summary>
        /// Load blocks from XML.
        /// </summary>
        /// <param name="xml">Text representation of XML.</param>
        /// <param name="workspace">Workspace.</param>
        private static void loadXml_(string xmlStr, WorkspaceSvg workspace)
        {
            Element xml;

            try {
                xml = Blockly.Xml.textToDom(xmlStr);
            }
            catch (Exception) {
                BlocklyStorage.alert(BlocklyStorage.XML_ERROR + "\nXML: " + xmlStr);
                return;
            }
            // Clear the workspace to avoid merge.
            workspace.clear();
            Blockly.Xml.domToWorkspace(xml, workspace);
        }
Пример #20
0
        /// <summary>
        /// Class for a WorkspaceFactoryGenerator
        /// </summary>
        public WorkspaceFactoryGenerator(WorkspaceFactoryModel model)
        {
            // Model to share information about categories and shadow blocks.
            this.model = model;
            // Create hidden workspace to load saved XML to generate toolbox XML.
            var hiddenBlocks = Document.CreateElement <HTMLDivElement>("div");
            // Generate a globally unique ID for the hidden div element to avoid
            // collisions.
            var hiddenBlocksId = Blockly.Core.genUid();

            hiddenBlocks.Id            = hiddenBlocksId;
            hiddenBlocks.Style.Display = Display.None;
            Document.Body.AppendChild(hiddenBlocks);
            this.hiddenWorkspace = Blockly.Core.inject(hiddenBlocksId);
        }
Пример #21
0
        /// <summary>
        /// Copy a block onto the local clipboard.
        /// </summary>
        /// <param name="block">Block to be copied.</param>
        private static void copy_(Block block)
        {
            var xmlBlock = Xml.blockToDom(block);

            if (Core.dragMode_ != Core.DRAG_FREE)
            {
                Xml.deleteNext(xmlBlock);
            }
            // Encode start position in XML.
            var xy = block.getRelativeToSurfaceXY();

            xmlBlock.SetAttribute("x", (block.RTL ? -xy.x : xy.x).ToString());
            xmlBlock.SetAttribute("y", xy.y.ToString());
            Core.clipboardXml_    = xmlBlock;
            Core.clipboardSource_ = (WorkspaceSvg)block.workspace;
        }
Пример #22
0
        /// <summary>
        /// Start monitoring the workspace.  If a change is made that changes the XML,
        /// clear the key from the URL.  Stop monitoring the workspace once such a
        /// change is detected.
        /// </summary>
        /// <param name="workspace">Workspace.</param>
        private static void monitorChanges_(WorkspaceSvg workspace)
        {
            var startXmlDom  = Blockly.Xml.workspaceToDom(workspace);
            var startXmlText = Blockly.Xml.domToText(startXmlDom);
            Action <Events.Abstract> bindData = null;
            var change = new Action <Events.Abstract>((e) => {
                var xmlDom  = Blockly.Xml.workspaceToDom(workspace);
                var xmlText = Blockly.Xml.domToText(xmlDom);
                if (startXmlText != xmlText)
                {
                    Window.Location.Hash = "";
                    workspace.removeChangeListener(bindData);
                }
            });

            bindData = workspace.addChangeListener(change);
        }
Пример #23
0
 /// <summary>
 /// Fire a new AJAX request.
 /// </summary>
 /// <param name="url">URL to fetch.</param>
 /// <param name="name">Name of parameter.</param>
 /// <param name="content">Content of parameter.</param>
 /// <param name="workspace">Workspace.</param>
 private static void makeRequest_(string url, string name, string content, WorkspaceSvg workspace)
 {
     if (BlocklyStorage.httpRequest_ != null)
     {
         // AJAX call is in-flight.
         BlocklyStorage.httpRequest_.Abort();
     }
     BlocklyStorage.httpRequest_      = new XMLHttpRequest();
     BlocklyStorage.httpRequest_.Name = name;
     BlocklyStorage.httpRequest_.OnReadyStateChange =
         new Action(BlocklyStorage.handleRequest_);
     BlocklyStorage.httpRequest_.Open("POST", url);
     BlocklyStorage.httpRequest_.SetRequestHeader("Content-Type",
                                                  "application/x-www-form-urlencoded");
     BlocklyStorage.httpRequest_.Send(name + "=" + Script.EncodeURIComponent(content));
     BlocklyStorage.httpRequest_["workspace"] = workspace;
 }
Пример #24
0
        /// <summary>
        /// Class for UI bubble.
        /// </summary>
        /// <param name="workspace">The workspace on which to draw the
        /// bubble.</param>
        /// <param name="content">SVG content for the bubble.</param>
        /// <param name="shape">SVG element to avoid eclipsing.</param>
        /// <param name="anchorXY">Absolute position of bubble's anchor
        /// point.</param>
        /// <param name="bubbleWidth">Width of bubble, or null if not resizable.</param>
        /// <param name="bubbleHeight">Height of bubble, or null if not resizable.</param>
        public Bubble(WorkspaceSvg workspace, SVGElement content, SVGElement shape,
                      goog.math.Coordinate anchorXY, double bubbleWidth, double bubbleHeight)
        {
            this.workspace_ = workspace;
            this.content_   = content;
            this.shape_     = shape;

            var angle = Bubble.ARROW_ANGLE;

            if (this.workspace_.RTL)
            {
                angle = -angle;
            }
            this.arrow_radians_ = goog.math.toRadians(angle);

            var canvas = workspace.getBubbleCanvas();

            canvas.AppendChild(this.createDom_(content, !(bubbleWidth != 0.0 && bubbleHeight != 0.0)));

            this.setAnchorLocation(anchorXY);
            if (bubbleWidth == 0.0 || bubbleHeight == 0.0)
            {
                var bBox = /** @type {SVGLocatable} */ (this.content_).getBBox();
                bubbleWidth  = bBox.width + 2 * Bubble.BORDER_WIDTH;
                bubbleHeight = bBox.height + 2 * Bubble.BORDER_WIDTH;
            }
            this.setBubbleSize(bubbleWidth, bubbleHeight);

            // Render the bubble.
            this.positionBubble_();
            this.renderArrow_();
            this.rendered_ = true;

            if (!workspace.options.readOnly)
            {
                Core.bindEventWithChecks_(this.bubbleBack_, "mousedown", this,
                                          new Action <MouseEvent>(this.bubbleMouseDown_));
                if (this.resizeGroup_ != null)
                {
                    Core.bindEventWithChecks_(this.resizeGroup_, "mousedown", this,
                                              new Action <MouseEvent>(this.resizeMouseDown_));
                }
            }
        }
Пример #25
0
        public Scrollbar(WorkspaceSvg workspace, bool horizontal, bool opt_pair = false)
        {
            this.workspace_      = workspace;
            this.pair_           = opt_pair;
            this.horizontal_     = horizontal;
            this.oldHostMetrics_ = null;

            this.createDom_();

            this.position_ = new goog.math.Coordinate(0, 0);

            if (horizontal)
            {
                this.svgBackground_.SetAttribute("height",
                                                 Scrollbar.scrollbarThickness.ToString());
                this.svgHandle_.SetAttribute("height",
                                             (Scrollbar.scrollbarThickness - 5).ToString());
                this.svgHandle_.SetAttribute("y", 2.5.ToString());

                this.lengthAttribute_   = "width";
                this.positionAttribute_ = "x";
            }
            else
            {
                this.svgBackground_.SetAttribute("width",
                                                 Scrollbar.scrollbarThickness.ToString());
                this.svgHandle_.SetAttribute("width",
                                             (Scrollbar.scrollbarThickness - 5).ToString());
                this.svgHandle_.SetAttribute("x", 2.5.ToString());

                this.lengthAttribute_   = "height";
                this.positionAttribute_ = "y";
            }
            var scrollbar = this;

            this.onMouseDownBarWrapper_ = Core.bindEventWithChecks_(
                this.svgBackground_, "mousedown", scrollbar, new Action <MouseEvent>(scrollbar.onMouseDownBar_));
            this.onMouseDownHandleWrapper_ = Core.bindEventWithChecks_(this.svgHandle_,
                                                                       "mousedown", scrollbar, new Action <MouseEvent>(scrollbar.onMouseDownHandle_));
        }
Пример #26
0
        /// <summary>
        /// Load sounds for the given workspace.
        /// </summary>
        /// <param name="pathToMedia">The path to the media directory.</param>
        /// <param name="workspace">The workspace to load sounds for.</param>
        private static void inject_loadSounds_(string pathToMedia, WorkspaceSvg workspace)
        {
            workspace.loadAudio_(new string[]
                                 { pathToMedia + "click.mp3",
                                   pathToMedia + "click.wav",
                                   pathToMedia + "click.ogg" }, "click");
            workspace.loadAudio_(new string[]
                                 { pathToMedia + "disconnect.wav",
                                   pathToMedia + "disconnect.mp3",
                                   pathToMedia + "disconnect.ogg" }, "disconnect");
            workspace.loadAudio_(new string[]
                                 { pathToMedia + "delete.mp3",
                                   pathToMedia + "delete.ogg",
                                   pathToMedia + "delete.wav" }, "delete");

            // Bind temporary hooks that preload the sounds.
            var soundBinds   = new JsArray <JsArray <EventWrapInfo> >();
            var unbindSounds = new Action <Event>((e) => {
                while (soundBinds.Length != 0)
                {
                    Core.unbindEvent_((JsArray <EventWrapInfo>)soundBinds.Pop());
                }
                workspace.preloadAudio_();
            });

            // These are bound on mouse/touch events with Blockly.bindEventWithChecks_, so
            // they restrict the touch identifier that will be recognized.  But this is
            // really something that happens on a click, not a drag, so that's not
            // necessary.

            // Android ignores any sound not loaded as a result of a user action.
            soundBinds.Push(
                Core.bindEventWithChecks_(Document.Instance, "mousemove", null, unbindSounds,
                                          true));
            soundBinds.Push(
                Core.bindEventWithChecks_(Document.Instance, "touchstart", null, unbindSounds,
                                          true));
        }
Пример #27
0
        /// <summary>
        /// Class for a Toolbox.
        /// Creates the toolbox's DOM.
        /// </summary>
        /// <param name="workspaceSvg">The workspace in which to create new</param>
        public Toolbox(WorkspaceSvg workspace)
        {
            this.workspace_        = workspace;
            this.RTL               = workspace.options.RTL;
            this.horizontalLayout_ = workspace.options.horizontalLayout;
            this.toolboxPosition   = workspace.options.toolboxPosition;
            this.config_           = new Config {
                indentWidth           = 19,
                cssRoot               = "blocklyTreeRoot",
                cssHideRoot           = "blocklyHidden",
                cssItem               = "",
                cssTreeRow            = "blocklyTreeRow",
                cssItemLabel          = "blocklyTreeLabel",
                cssTreeIcon           = "blocklyTreeIcon",
                cssExpandedFolderIcon = "blocklyTreeIconOpen",
                cssFileIcon           = "blocklyTreeIconNone",
                cssSelectedRow        = "blocklyTreeSelected"
            };

            this.treeSeparatorConfig_ = new Config {
                cssTreeRow = "blocklyTreeSeparator"
            };

            if (this.horizontalLayout_)
            {
                this.config_.cssTreeRow =
                    this.config_.cssTreeRow +
                    (workspace.RTL ?
                     " blocklyHorizontalTreeRtl" : " blocklyHorizontalTree");

                this.treeSeparatorConfig_.cssTreeRow =
                    "blocklyTreeSeparatorHorizontal " +
                    (workspace.RTL ?
                     "blocklyHorizontalTreeRtl" : "blocklyHorizontalTree");
                this.config_.cssTreeIcon = "";
            }
        }
Пример #28
0
 /// <summary>
 /// Class for a zoom controls.
 /// </summary>
 /// <param name="workspace">The workspace to sit in.</param>
 public ZoomControls(WorkspaceSvg workspace)
 {
     this.workspace_ = workspace;
 }
Пример #29
0
 /// <summary>
 /// Size the workspace when the contents change.  This also updates
 /// scrollbars accordingly.
 /// </summary>
 /// <param name="workspace"></param>
 public static void resizeSvgContents(WorkspaceSvg workspace)
 {
     workspace.resizeContents();
 }
Пример #30
0
        /// <summary>
        /// Create a main workspace and add it to the SVG.
        /// </summary>
        /// <param name="svg">SVG element with pattern defined.</param>
        /// <param name="options">Dictionary of options.</param>
        /// <returns>Newly created main workspace.</returns>
        private static WorkspaceSvg createMainWorkspace_(SVGElement svg, Options options)
        {
            options.parentWorkspace = null;
            var mainWorkspace = new WorkspaceSvg(options);

            mainWorkspace.scale = options.zoomOptions.startScale;
            svg.AppendChild(mainWorkspace.createDom("blocklyMainBackground"));
            // A null translation will also apply the correct initial scale.
            mainWorkspace.translate(0, 0);
            mainWorkspace.markFocused(null);

            if (!options.readOnly && !options.hasScrollbars)
            {
                var workspaceChanged = new Action <Events.Abstract>((e) => {
                    if (Core.dragMode_ == Core.DRAG_NONE)
                    {
                        var metrics  = mainWorkspace.getMetrics();
                        var edgeLeft = metrics.viewLeft + metrics.absoluteLeft;
                        var edgeTop  = metrics.viewTop + metrics.absoluteTop;
                        if (metrics.contentTop < edgeTop ||
                            metrics.contentTop + metrics.contentHeight >
                            metrics.viewHeight + edgeTop ||
                            metrics.contentLeft <
                            (options.RTL ? metrics.viewLeft : edgeLeft) ||
                            metrics.contentLeft + metrics.contentWidth > (options.RTL ?
                                                                          metrics.viewWidth : metrics.viewWidth + edgeLeft))
                        {
                            // One or more blocks may be out of bounds.  Bump them back in.
                            var MARGIN = 25;
                            var blocks = mainWorkspace.getTopBlocks(false);
                            foreach (var block in blocks)
                            {
                                var blockXY = block.getRelativeToSurfaceXY();
                                var blockHW = ((BlockSvg)block).getHeightWidth();
                                // Bump any block that's above the top back inside.
                                var overflowTop = edgeTop + MARGIN - blockHW.height - blockXY.y;
                                if (overflowTop > 0)
                                {
                                    block.moveBy(0, overflowTop);
                                }
                                // Bump any block that's below the bottom back inside.
                                var overflowBottom =
                                    edgeTop + metrics.viewHeight - MARGIN - blockXY.y;
                                if (overflowBottom < 0)
                                {
                                    block.moveBy(0, overflowBottom);
                                }
                                // Bump any block that's off the left back inside.
                                var overflowLeft = MARGIN + edgeLeft -
                                                   blockXY.x - (options.RTL ? 0 : blockHW.width);
                                if (overflowLeft > 0)
                                {
                                    block.moveBy(overflowLeft, 0);
                                }
                                // Bump any block that's off the right back inside.
                                var overflowRight = edgeLeft + metrics.viewWidth - MARGIN -
                                                    blockXY.x + (options.RTL ? blockHW.width : 0);
                                if (overflowRight < 0)
                                {
                                    block.moveBy(overflowRight, 0);
                                }
                            }
                        }
                    }
                });
                mainWorkspace.addChangeListener(workspaceChanged);
            }
            // The SVG is now fully assembled.
            Core.svgResize(mainWorkspace);
            WidgetDiv.createDom();
            Tooltip.createDom();
            return(mainWorkspace);
        }