1104
0 parents
Showing
2 changed files
with
274 additions
and
0 deletions
1104/1104.md
0 → 100644
| 1 | 其中部分函数 例如初始化函数53-54行 | ||
| 2 | |||
| 3 | ``` | ||
| 4 | // 重建dom | ||
| 5 | this.fieldGroup_ = Blockly.utils.createSvgElement('g', {}, null); | ||
| 6 | this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_); | ||
| 7 | ``` | ||
| 8 | |||
| 9 | 查询了chatgpt,但具体含义不算特别了解 不知道写同类型组件时是不是照抄就好了 | ||
| 10 | |||
| 11 | |||
| 12 | |||
| 13 | 再例如111行 | ||
| 14 | |||
| 15 | ``` | ||
| 16 | Blockly.FieldIconDropDown.prototype.setParentFieldImage = function (src) { | ||
| 17 | if (this.imageElement_ && src) { | ||
| 18 | this.imageElement_.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', src || ''); | ||
| 19 | } | ||
| 20 | }; | ||
| 21 | ``` | ||
| 22 | |||
| 23 | 经chatgpt解释 | ||
| 24 | |||
| 25 | - ``` | ||
| 26 | this.imageElement_.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', src || ''); | ||
| 27 | ``` | ||
| 28 | |||
| 29 | - `this.imageElement_` 是一个图像元素,可能是一个 SVG 图像。 | ||
| 30 | - `setAttributeNS` 是设置元素属性的方法,使用了命名空间(namespace),这里指定了 `http://www.w3.org/1999/xlink`,这是用于处理链接的命名空间。 | ||
| 31 | - `'xlink:href'` 是要设置的属性,表示图像的链接。 | ||
| 32 | - `src || ''` 表示如果 `src` 存在,就使用它;如果 `src` 为假值(例如 `null` 或 `undefined`),则使用空字符串 `''`。 | ||
| 33 | |||
| 34 | 但还是不太清楚这种函数是怎么写出来的 为什么要写成这样 | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
1104/field_icon_dropdown.js
0 → 100644
| 1 | 'use strict'; | ||
| 2 | |||
| 3 | goog.provide('Blockly.FieldIconDropDown'); | ||
| 4 | goog.require('Blockly.DropDownDiv'); | ||
| 5 | |||
| 6 | |||
| 7 | /** | ||
| 8 | * 构造器 | ||
| 9 | * @param icons | ||
| 10 | * @constructor | ||
| 11 | */ | ||
| 12 | Blockly.FieldIconDropDown = function (icons) { | ||
| 13 | this.icons_ = icons; | ||
| 14 | // Example: | ||
| 15 | // [{src: '...', width: 20, height: 20, value: 'machine_value'}, ...] | ||
| 16 | // 选择第一个为默认值 | ||
| 17 | const defaultValue = icons[0].value; | ||
| 18 | Blockly.FieldIconDropDown.superClass_.constructor.call(this, defaultValue); | ||
| 19 | // this.addArgType('icon_dropdown'); | ||
| 20 | }; | ||
| 21 | goog.inherits(Blockly.FieldIconDropDown, Blockly.Field); | ||
| 22 | |||
| 23 | /** | ||
| 24 | * Json配置 | ||
| 25 | */ | ||
| 26 | Blockly.FieldIconDropDown.fromJson = function (element) { | ||
| 27 | return new Blockly.FieldIconDropDown(element['options']); | ||
| 28 | }; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * 下拉面板宽度(不需要修改,3个图标宽度) | ||
| 32 | * @type {number} | ||
| 33 | * @const | ||
| 34 | */ | ||
| 35 | Blockly.FieldIconDropDown.DROPDOWN_WIDTH = 168; | ||
| 36 | |||
| 37 | /** | ||
| 38 | * 颜色记录 | ||
| 39 | */ | ||
| 40 | Blockly.FieldIconDropDown.savedPrimary_ = null; | ||
| 41 | |||
| 42 | /** | ||
| 43 | * 初始化 | ||
| 44 | */ | ||
| 45 | Blockly.FieldIconDropDown.prototype.init = function (block) { | ||
| 46 | if (this.fieldGroup_) { | ||
| 47 | return; | ||
| 48 | } | ||
| 49 | // 下拉箭头大小 | ||
| 50 | const arrowSize = 12; | ||
| 51 | |||
| 52 | // 重建dom | ||
| 53 | this.fieldGroup_ = Blockly.utils.createSvgElement('g', {}, null); | ||
| 54 | this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_); | ||
| 55 | |||
| 56 | // 字段宽度 | ||
| 57 | this.size_.width = 44; | ||
| 58 | |||
| 59 | // 图标 | ||
| 60 | this.imageElement_ = Blockly.utils.createSvgElement('image', { | ||
| 61 | 'height': 24 + 'px', | ||
| 62 | 'width': 24 + 'px', | ||
| 63 | 'x': 4 + "px", | ||
| 64 | 'y': 4 + "px", | ||
| 65 | }, this.fieldGroup_); | ||
| 66 | this.setParentFieldImage(this.getSrcForValue(this.value_)); | ||
| 67 | |||
| 68 | // 下拉箭头位置 | ||
| 69 | this.arrowX_ = 32; | ||
| 70 | this.arrowY_ = 10; | ||
| 71 | if (block.RTL) { | ||
| 72 | this.arrowX_ = -this.arrowX_ - arrowSize; | ||
| 73 | } | ||
| 74 | |||
| 75 | // 下拉图标 | ||
| 76 | this.arrowIcon_ = Blockly.utils.createSvgElement('image', { | ||
| 77 | 'height': arrowSize + 'px', | ||
| 78 | 'width': arrowSize + 'px', | ||
| 79 | 'transform': 'translate(' + this.arrowX_ + ',' + this.arrowY_ + ')' | ||
| 80 | }, this.fieldGroup_); | ||
| 81 | this.arrowIcon_.setAttributeNS('http://www.w3.org/1999/xlink', | ||
| 82 | 'xlink:href', Blockly.mainWorkspace.options.pathToMedia + 'dropdown-arrow.svg'); | ||
| 83 | |||
| 84 | this.mouseDownWrapper_ = Blockly.bindEventWithChecks_( | ||
| 85 | this.getClickTarget_(), 'mousedown', this, this.onMouseDown_); | ||
| 86 | }; | ||
| 87 | |||
| 88 | /** | ||
| 89 | * 鼠标放置样式 | ||
| 90 | */ | ||
| 91 | Blockly.FieldIconDropDown.prototype.CURSOR = 'default'; | ||
| 92 | |||
| 93 | /** | ||
| 94 | * 设置值 | ||
| 95 | */ | ||
| 96 | Blockly.FieldIconDropDown.prototype.setValue = function (newValue) { | ||
| 97 | if (newValue === null || newValue === this.value_) { | ||
| 98 | return; // No change | ||
| 99 | } | ||
| 100 | if (this.sourceBlock_ && Blockly.Events.isEnabled()) { | ||
| 101 | Blockly.Events.fire(new Blockly.Events.Change( | ||
| 102 | this.sourceBlock_, 'field', this.name, this.value_, newValue)); | ||
| 103 | } | ||
| 104 | this.value_ = newValue; | ||
| 105 | this.setParentFieldImage(this.getSrcForValue(this.value_)); | ||
| 106 | }; | ||
| 107 | |||
| 108 | /** | ||
| 109 | * 设置当前选择图片 | ||
| 110 | */ | ||
| 111 | Blockly.FieldIconDropDown.prototype.setParentFieldImage = function (src) { | ||
| 112 | if (this.imageElement_ && src) { | ||
| 113 | this.imageElement_.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', src || ''); | ||
| 114 | } | ||
| 115 | }; | ||
| 116 | |||
| 117 | /** | ||
| 118 | * 获取值 | ||
| 119 | */ | ||
| 120 | Blockly.FieldIconDropDown.prototype.getValue = function () { | ||
| 121 | return this.value_; | ||
| 122 | }; | ||
| 123 | |||
| 124 | /** | ||
| 125 | * 根据src获取值 | ||
| 126 | * @param value | ||
| 127 | * @returns {*} | ||
| 128 | */ | ||
| 129 | Blockly.FieldIconDropDown.prototype.getSrcForValue = function (value) { | ||
| 130 | for (var i = 0, icon; icon = this.icons_[i]; i++) { | ||
| 131 | if (icon.value === value) { | ||
| 132 | return icon.src; | ||
| 133 | } | ||
| 134 | } | ||
| 135 | }; | ||
| 136 | |||
| 137 | /** | ||
| 138 | * 下拉选择 | ||
| 139 | */ | ||
| 140 | Blockly.FieldIconDropDown.prototype.showEditor_ = function () { | ||
| 141 | if (Blockly.DropDownDiv.hideIfOwner(this)) { // 如果有下拉面板,关闭 | ||
| 142 | return; | ||
| 143 | } | ||
| 144 | Blockly.DropDownDiv.hideWithoutAnimation(); | ||
| 145 | Blockly.DropDownDiv.clearContent(); // 清空内容 | ||
| 146 | // 构建下拉内容 | ||
| 147 | const contentDiv = Blockly.DropDownDiv.getContentDiv(); | ||
| 148 | // Accessibility properties | ||
| 149 | contentDiv.setAttribute('role', 'menu'); | ||
| 150 | contentDiv.setAttribute('aria-haspopup', 'true'); // 设置为true,表示有下拉面板 | ||
| 151 | for (let i = 0, icon; icon = this.icons_[i]; i++) { | ||
| 152 | |||
| 153 | // 按钮 | ||
| 154 | const button = document.createElement('button'); | ||
| 155 | button.setAttribute('id', ':' + i); | ||
| 156 | button.setAttribute('role', 'menuitem'); | ||
| 157 | button.setAttribute('class', 'blocklyDropDownButton'); | ||
| 158 | button.title = icon.alt; | ||
| 159 | button.style.width = icon.width + 'px'; | ||
| 160 | button.style.height = icon.height + 'px'; | ||
| 161 | let backgroundColor = this.sourceBlock_.getColour(); | ||
| 162 | if (icon.value === this.getValue()) { // 选中, 则设置背景色 | ||
| 163 | |||
| 164 | backgroundColor = this.sourceBlock_.getColourTertiary(); // 设置为三级颜色 | ||
| 165 | button.setAttribute('aria-selected', 'true'); // 设置为选中 | ||
| 166 | } | ||
| 167 | button.style.backgroundColor = backgroundColor; | ||
| 168 | button.style.borderColor = this.sourceBlock_.getColourTertiary(); // 设置边框颜色 | ||
| 169 | |||
| 170 | // 事件 | ||
| 171 | Blockly.bindEvent_(button, 'click', this, this.buttonClick_); | ||
| 172 | Blockly.bindEvent_(button, 'mouseup', this, this.buttonClick_); | ||
| 173 | Blockly.bindEvent_(button, 'mousedown', button, function (e) { | ||
| 174 | this.setAttribute('class', 'blocklyDropDownButton blocklyDropDownButtonHover'); //增加hover样式(点击时) | ||
| 175 | e.preventDefault(); | ||
| 176 | }); | ||
| 177 | Blockly.bindEvent_(button, 'mouseover', button, function () { | ||
| 178 | this.setAttribute('class', 'blocklyDropDownButton blocklyDropDownButtonHover'); //增加hover样式(鼠标悬浮) | ||
| 179 | contentDiv.setAttribute('aria-activedescendant', this.id); | ||
| 180 | }); | ||
| 181 | Blockly.bindEvent_(button, 'mouseout', button, function () { | ||
| 182 | this.setAttribute('class', 'blocklyDropDownButton'); | ||
| 183 | contentDiv.removeAttribute('aria-activedescendant'); // 移除激活的子元素 | ||
| 184 | }); | ||
| 185 | |||
| 186 | // 图标 | ||
| 187 | const buttonImg = document.createElement('img'); | ||
| 188 | buttonImg.src = icon.src; | ||
| 189 | button.setAttribute('data-value', icon.value); | ||
| 190 | buttonImg.setAttribute('data-value', icon.value); | ||
| 191 | button.appendChild(buttonImg); // 添加图标 | ||
| 192 | contentDiv.appendChild(button); // 添加按钮 | ||
| 193 | } | ||
| 194 | contentDiv.style.width = Blockly.FieldIconDropDown.DROPDOWN_WIDTH + 'px'; | ||
| 195 | |||
| 196 | // 设置颜色 | ||
| 197 | Blockly.DropDownDiv.setColour(this.sourceBlock_.getColour(), this.sourceBlock_.getColourTertiary()); | ||
| 198 | Blockly.DropDownDiv.setCategory(this.sourceBlock_.parentBlock_.getCategory()); | ||
| 199 | this.savedPrimary_ = this.sourceBlock_.getColour(); | ||
| 200 | this.sourceBlock_.setColour(this.sourceBlock_.getColourSecondary(), | ||
| 201 | this.sourceBlock_.getColourSecondary(), | ||
| 202 | this.sourceBlock_.getColourTertiary()); | ||
| 203 | |||
| 204 | const scale = this.sourceBlock_.workspace.scale; | ||
| 205 | const secondaryYOffset = ( | ||
| 206 | -(Blockly.BlockSvg.MIN_BLOCK_Y * scale) - (Blockly.BlockSvg.FIELD_Y_OFFSET * scale) | ||
| 207 | ); | ||
| 208 | const renderedPrimary = Blockly.DropDownDiv.showPositionedByBlock(this, this.sourceBlock_, this.onHide_.bind(this), secondaryYOffset); | ||
| 209 | if (!renderedPrimary) { | ||
| 210 | const arrowX = this.arrowX_ + Blockly.DropDownDiv.ARROW_SIZE / 1.5 + 1; | ||
| 211 | const arrowY = this.arrowY_ + Blockly.DropDownDiv.ARROW_SIZE / 1.5; | ||
| 212 | this.arrowIcon_.setAttribute('transform', 'translate(' + arrowX + ',' + arrowY + ') rotate(180)'); | ||
| 213 | } | ||
| 214 | }; | ||
| 215 | |||
| 216 | /** | ||
| 217 | * 点击按钮 | ||
| 218 | */ | ||
| 219 | Blockly.FieldIconDropDown.prototype.buttonClick_ = function (e) { | ||
| 220 | const value = e.target.getAttribute('data-value'); | ||
| 221 | this.setValue(value); // 设置值 | ||
| 222 | Blockly.DropDownDiv.hide(); // 隐藏下拉面板 | ||
| 223 | }; | ||
| 224 | |||
| 225 | /** | ||
| 226 | * 关闭下拉面板时回掉 | ||
| 227 | */ | ||
| 228 | Blockly.FieldIconDropDown.prototype.onHide_ = function () { | ||
| 229 | if (this.sourceBlock_) { | ||
| 230 | this.sourceBlock_.setColour(this.savedPrimary_, | ||
| 231 | this.sourceBlock_.getColourSecondary(), | ||
| 232 | this.sourceBlock_.getColourTertiary()); | ||
| 233 | } | ||
| 234 | Blockly.DropDownDiv.content_.removeAttribute('role'); | ||
| 235 | Blockly.DropDownDiv.content_.removeAttribute('aria-haspopup'); | ||
| 236 | Blockly.DropDownDiv.content_.removeAttribute('aria-activedescendant'); | ||
| 237 | this.arrowIcon_.setAttribute('transform', 'translate(' + this.arrowX_ + ',' + this.arrowY_ + ')'); | ||
| 238 | }; | ||
| 239 | |||
| 240 | Blockly.Field.register('field_icon_dropdown', Blockly.FieldIconDropDown); // 注册字段作为自定义类型 | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or sign in to post a comment