Инструменты пользователя

Инструменты сайта


library

Внимание! На данный момент система поддерживает работу со скриптами только на языке JavaScript, в связи с этим для понимания этой статьи необходимо обладать базовыми навыками работы с этим языком.

Структура файлов библиотек

Все библиотеки СКАДА системы находятся в незапакованном виде и доступны для просмотра и редактирования, однако редактировать библиотеки дистрибутива не рекомендуется, тк это может нарушить работу проектов, разработанных с их использованием.
Папка с библиотеками находится в папке установки СКАДА системы и имеет следующий путь:

resources\app.asar.unpacked\lib

Если СКАДА установлена в папку по умолчанию, то полный путь будет таким:

C:\Users\<Имя_пользователя>\AppData\Local\Programs\DevelSCADA\resources\app.asar.unpacked\lib

Все папки находящиеся в этой папке будут восприняты системой как библиотеки компонентов. Имя библиотеки будет соответствовать названию папки. Так же в этой папке могут находиться вспомогательные скрипты, которые используются в коде библиотек (к примеру системный скрипт dsUtils.js).
Внутри папки должен находиться файл скрипта с именем main.js, в котором описывается список компонентов библиотеки и логика их работы. Скрипты подключаются к проекту как модули. Так же в папке библиотеки могут находиться необходимые для нее ресурсы, чаще всего это файлы изображений компонентов библиотеки.

Скрипт библиотеки

В скрипте библиотеки необходимо экспортировать переменную с именем libList, которая должна содержать массив создаваемых компонентов. Каждый элемент массива - это объект, описывающий свойства и логику работы компонента библиотеки. Каждый компонент обязательно должен содержать следующие поля:

id - уникальное имя компонента внутри библиотеки;
name - имя библиотеки, которое будет отображаться текстом в среде разработке.

Для примера сделаем библиотеку. Для этого создадим в директории библиотек новую папку с названием «Моя библиотека», в ней создадим файл main.js, в файл напишем следующий код:

export let libList = [];
 
libList.push({
	id: 'comp',
	name: 'Компонент'
});

После этого перезапустим среду разработки и мы должны увидеть нашу новую библиотеку и в ней наш компонент, который мы уже можем использовать и вытащить на рабочее поле.


Сейчас компонент не имеет никаких свойств и в качестве своего изображения использует стандартную заглушку. Чтобы использовать свою иконку компонента в списке библиотек, необходимо добавить свойство icon, в котором указать путь к файлу изображения иконки (путь указывается относительно собственной папки библиотеки). Для изображения самого компонента в рабочей области редактора, его необходимо указать в свойстве image. В качестве иконки и изображения можно использовать один и тот же файл изображения, однако если изображение достаточно большое, то в качестве иконки желательно сделать уменьшенную ее копию для ускорения работы среды разработки. Для примера создадим изображение и положим его в папку с библиотекой и назовем файл iamage.png и пропишем его в свойствах нашего компонента.
Так же в свойствах можно прописать размеры компонента, которые будут выставлены при его создании (по умолчанию создается размером 100 на 100 пикселей). Для этого используются свойства width и height.
Помимо явного указания свойств компонента можно использовать шаблон, прописывая его имя в свойстве template, однако сами шаблоны жестко прописаны в системе и не могут быть изменены пользователем, поэтому они в основном используются для системных компонентов и в данной статье рассматриваться не будут.
Ну и чтобы компонент мог хранить свои свойства при редактировании, необходимо указать их список в свойстве prop. Подробнее об этом свойстве будет рассказано ниже. Следует обратить внимание что вышеописанные свойства используются только при создании компонента, а из списка свойств в prop формируется список свойств компонента при манипулировании им.
Обычно все компоненты имеют список стандартных свойств, таких как размеры, положение, прозрачность и тд, чтобы не описывать их каждый раз для нового компонента вручную, существует функция конструктор свойств, которая находится в файле модуля dsUtils.js, воспользуемся ею для создания списка стандартных свойств компонента. В результате у нас должен получиться такой код:

import { crtProp } from '../dsUtils.js';
 
export let libList = [];
 
libList.push({
	id: 'comp',
	name: 'Компонент',
	icon: 'image.png',
	image: 'image.png',
	width: 100,
	height: 100,
	prop: crtProp()
});

После этого перезапускаем среду разработки можем уже полноценно пользоваться новым компонентом (перезапускать среду необходимо после каждого изменения, внесенного в библиотеку для того чтобы она заново прогрузила их). В результате должны получить следующее:


Так же у нашего компонента теперь появился список стандартных свойств:


Добавление свойств компонента

Компоненты обычно создаются под какие-то конкретные задачи, которым не соответствуют компоненты стандартных библиотек, поэтому имеется возможность переопределять стандартные свойства или расширять, добавляя собственные. Для примера добавить новое свойство, которое будет отображать рамку вокруг нашего компонента. Как было сказано ранее, список свойств задается в prop, где создавался список стандартных свойств функцией crtProp, но чтобы не затирать его а дополнить нашими, их можно указать в качестве аргумента этой функции в виде массива.
Объект свойства должен содержать обязательно следующие поля:

id - имя свойства, которое используется в коде при обращении к нему. Должно быть уникальным в списке свойств каждого компонента, при этом если оно совпадает с именем стандартного свойства, то оно будет переопределено новым кодом;
text - название свойства, которое будет отображаться в редакторе в списке свойств компонента;
type - тип данных свойства, на данный момент доступны следующие: string, number, bool, color и image;
initVal - значение, выставляемое свойству при создании компонента.

Исправим код следующим образом:

import { crtProp } from '../dsUtils.js';
 
export let libList = [];
 
let myProp = {
	id: 'border',
	text: 'Рамка',
	type: 'bool',
	initVal: false
};
 
libList.push({
	id: 'comp',
	name: 'Компонент',
	icon: 'image.png',
	image: 'image.png',
	width: 100,
	height: 100,
	prop: crtProp([ myProp ])
});

В результате в редакторе увидим наше новое свойство:


Теперь нам необходимо написать код обработки, который будет вызываться при изменении свойства компонента. При этом следует обратить внимание что есть код обработки изменения свойства в редакторе, а есть в среде исполнения. Тк нам важно чтобы компонент реагировал на изменения в процессе работы, код обработки в редакторе в данной статье рассматриваться не будет (кому интересно, может посмотреть в примерах системных библиотек).
Код обработки описывается функцией в свойстве setFunc, при этом функции передается контекст исполнения текущего компонента и устанавливаемое в свойстве значение. В контексте исполнения для компонентов, у которого в качестве изображения используется обычная картинка, в свойстве img передается объект jQuery, с которым можно производить любые манипуляции. В нашем примере мы будем через CSS, в зависимости от значения свойства, отображать или скрывать рамку. Для этого исправим код следующим образом:

import { crtProp } from '../dsUtils.js';
 
export let libList = [];
 
let myProp = {
	id: 'border',
	text: 'Рамка',
	type: 'bool',
	initVal: false,
	setFunc: (d, val) => {
		if (val) d.img.css('border', '10px solid black');
		else d.img.css('border', '0px');
	}
};
 
libList.push({
	id: 'comp',
	name: 'Компонент',
	icon: 'image.png',
	image: 'image.png',
	width: 100,
	height: 100,
	prop: crtProp([ myProp ])
});

Теперь для проверки работы нашего свойства добавим на рабочее поле кнопку, в которой напишем код, который будет его изменять, следующего вида:

async function main() {
    let state = ds.getProp('obj0', 'border');
    state = !state;
    ds.setProp('obj0', 'border', state);
}

где:

obj0 - имя объекта нашего компонента на рабочем поле;
border - имя нашего свойства.

Код получает текущее значение свойства, тк оно булевое, инвертирует его и записывает обратно. В результате при нажатии кнопки рамка у нас будет появляться/прятаться.
Выглядеть это будет примерно так:


При работе нашего компонента можно заметить что нижний правый угол смещается на 20 пикселей, тк ширина рамки 10 пикселей, что выглядит не совсем эстетично. Чтобы исправить это и изображение оставалось на своем месте, мы можем при отображении рамки смещать верхний левый угол на ширину рамки, те 10 пикселей, тогда визуально само изображение не поменяет своего местоположения. Получить установить собственные свойства компонент может через функции getProp/setProp контекста. Поправим код следующим образом:

import { crtProp } from '../dsUtils.js';
 
export let libList = [];
 
let myProp = {
	id: 'border',
	text: 'Рамка',
	type: 'bool',
	initVal: false,
	setFunc: (d, val) => {
		let posx = d.getProp('posx');
		let posy = d.getProp('posy');
 
		if (val) {
			d.img.css('border', '10px solid black');
			d.setProp('posx', posx - 10);
			d.setProp('posy', posy - 10);
		} else {
			d.img.css('border', '0px');
			d.setProp('posx', posx + 10);
			d.setProp('posy', posy + 10);
		}
	}
};
 
libList.push({
	id: 'comp',
	name: 'Компонент',
	icon: 'image.png',
	image: 'image.png',
	width: 100,
	height: 100,
	prop: crtProp([ myProp ])
});

Редактирование свойств SVG изображений

Использование в качестве изображений векторные изображения в формате SVG значительно расширяет возможности манипуляции таким изображением, тк файлы SVG позволяют редактировать свойства отдельных элементов изображения, а СКАДА система, в свою очередь предоставляет полный доступ к таким возможностям. Для примера создадим изображение в редакторе Inkscape и привяжем свойства нашего компонента к элементам этого изображения.
В редакторе в меню «Файл» → «Свойства документа…» выставим размер страницы, который будет соответствовать размерам нашего компонента.


Создадим необходимое нам изображение, после чего нам нужно указать идентификаторы объектов, к которым мы в дальнейшем будем обращаться из кода. Для этого необходимо включить панель в меню «Правка» → «Редактор XML…», после чего выделить необходимый элемент и в открывшейся панели выставить id, к примеру в нашем случае назовем его mycirc.

После чего сохраним файл в папке библиотеки под именем rect.svg, а в коде исправим свойства icon и image и сделаем свойство «Цвет» таким образом:

import { crtProp } from '../dsUtils.js';
 
export let libList = [];
 
libList.push({
	id: 'comp',
	name: 'Компонент',
	icon: 'rect.svg',
	image: 'rect.svg',
	width: 100, height: 100,
	prop: crtProp([{
		id: 'circColor',
		text: 'Цвет',
		type: 'color',
		initVal: 'rgb(0,255,0)',
		setFunc: (d, val) => {
			d.svg.find('#mycirc').css('fill', val);
		}
	}])
});

В коде обработчика свойства мы в контексте компонента получаем объект SVG изображения, внутри него находим элемент с идентификатором mycirc, который мы ранее указали в Inkscape-е, и устанавливаем новый цвет заливки, который получает свойство компонента.
В кнопке напишем код, который будет выставлять в свойство случайный цвет:

async function main() {
    let colVal = [];
 
    for (let i = 0; i < 3; i++) {
        colVal.push(parseInt(Math.random() * 255));
    }
 
    let color = 'rgb(' + colVal.join(',') + ')';
    ds.setProp('obj0', 'circColor', color);
}

В результате при каждом нажатии на кнопку у нас будет меняться цвет внутри кругляшка случайным образом.


library.txt · Последнее изменение: 2022/06/22 12:56 — root