[Из песочницы] Как подружить Electron и Webix

Введение


Доброе время суток! Хотелось поделиться с Вами личным опытом создания десктопного приложения на JavaScript с использованием связки Electron и Webix. Такая связка позволяет ускорить процесс верстки интерфейса, особо не тратя время на разметку и прочие web штуки, которыми может заняться как раз фреймворк Webix.

Инструменты


Итак приступим, на понадобится следующие инструменты:

  1. Редактор, в котором мы будем писать непосредственно наш код. Я буду использовать visual studio code (VSC), который можно взять отсюда code.visualstudio.com/;
  2. Сервер Node.js, который можно взять от сюда nodejs.org/ru. Скачиваем его и устанавливаем;
  3. Фреймворк webix бесплатную версию (Webix Standard is a free UI library under GNU GPLv3 license), которую берем вот отсюда webix.com/get-webix-gpl. Для того что бы его скачать нужно перейти по выше приведенной ссылке, вести email, имя и фамилию, поставить три галочки нажать отправить после чего Вам на почту отправят ссылку для скачивания.


В общем то вот и все, что нам с Вами потребуется.

Устанавливаем необходимые инструменты


Итак, переходим непосредственно к созданию:

1. Устанавливаем node.js. Тут я останавливаться не буду я уверен с этим Вы справитесь без меня.

2. Создаем папку, в которой будем писать наш код — например electron_webix (рис. 1).

95upojfy4yfhuxkc_deex4boowk.png
Рис. 1 — Создание рабочей папки

3. Запускаем VSC и открываем эту папку (рис. 2).

6bxjrm4zr4aevp5caquooelxe_0.png
Рис. 2 — Открываем рабочую папку

4. Открываем в VSC терминал комбинацией клавиш «Ctr+`» и вводим команду «npm init», которая произведет инициализацию нашего «node.js» проекта. После чего система запросит кучу разных и очень полезных вопросов, на которые отвечать не обязательно поэтом жмем все время уверенно на «Enter» и не думаем не о чем плохом (рис. 3).

htd4sgxtbvuhuz0-rwphtnonn8a.png
Рис. 3 — Инициализация проекта

5. Устанавливаем непосредственно сам «Electron». Для чего в консоли VSC вводим команду «npm install --save-dev electron», после сидим и ждем пока все установиться (рис. 4).

zwlgfj03gwnvygcmnkubiht0yc0.png
Рис. 4 — Установка «Electron»

Организация рабочего пространства


Теперь переходим к организации рабочее пространство. Первое что мы должны сделать это создать несколько папок и файлов, без которых не обойтись (рис. 5):

  • папку «libs», сюда положим файлы скаченные с сайта «Webix»;
  • папку ».vscode», сюда положим json файл, который будет запускать наше приложение в VSC;
  • файл «main.js», основной файл, который будет запускать наше приложения «Electron»;
  • файл index.html, будет содержать наш контент и разметку;
  • файл «renderer.js», обработчик событий нашего приложения. Работает в связке с index.html;
  • файл «launch.json», в папке ».vscode» файл который нужен для запуска нашего кода в среде «VSC» кнопочкой «F5»;
  • файл «style.css», в этом файле нам все таки придется прописать кое какие стили что бы наше окошко выглядело по приличней.


z482x-r0o_a7formfm17hgdz1h4.png
Рис. 5 — Необходимое папки и файлы

Наполняем рабочее пространство первоначальным содержимым


Начнем наполнение рабочего пространства с файла «launch.json», который используется для запуска нашего приложения в среде «VSC» без всяких дополнительных команд из консоли.
Содержимое файл «launch.json» было взято вот отсюда. Тут мы не будем вникать в содержимое данного файла просто его скопируем и сохраним. Содержимое файла представлено ниже (рис. 6).

  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug Main Process",
      "type": "node",
      "request": "launch",
      "cwd": "${workspaceFolder}",
      "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
      "windows": {
        "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron.cmd"
      },
      "args" : ["."],
      "outputCapture": "std"
    }
  ]
}


mnvdikapsrdijhiazznrymzsiq4.png
Рис. 6 — Файл «launch.json» в среде «VSC»

Далее нам необходимо подправить немного файл «package.json», который был автоматически создан при выполнении команды «npm init». В нем нужно произвести изменение в двух строках как показано ниже (рис. 7):

Был вот такой «package.json»:

  "name": "electron_webix",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
  "test": "echo \"Error: no test specified\" && exit 1
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "electron": "^8.2.3"
  }
}


Стал вот такой «package.json»:

{
  "name": "electron_webix",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
   "start": "electron ."
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "electron": "^8.2.3"
  }
}


ben-7bzv8ffkqu-iv6avcr6yej4.png
Рис. 7 — Файл «package.json» в среде «VSC»

Теперь переходим к наполнению файла «main.js», его содержимое копируем вот отсюда. Вставляем и сохраняем.

const { app, BrowserWindow } = require('electron')

function createWindow () {
  // Создаем окно браузера.
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true
    }
  })

  // and load the index.html of the app.
  win.loadFile('index.html')

  // Отображаем средства разработчика.
  win.webContents.openDevTools()
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Некоторые API могут использоваться только после возникновения этого события.
app.whenReady().then(createWindow)

// Quit when all windows are closed.
app.on('window-all-closed', () => {
  // Для приложений и строки меню в macOS является обычным делом оставаться
  // активными до тех пор, пока пользователь не выйдет окончательно используя Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', () => {
   // На MacOS обычно пересоздают окно в приложении,
   // после того, как на иконку в доке нажали и других открытых окон нету.
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow()
  }
})

// In this file you can include the rest of your app's specific main process
// code. Можно также поместить их в отдельные файлы и применить к ним require.


ebds8lo5bx4t2mmn1idqdo0ucma.png
Рис. 8 — Файл «main.js» в среде «VSC»

После чего мы уже можем наконец то выполнить первый запуск «клавиша F5» нашего приложения. Итак, жмем «F5» и вот оно наше окошко (рис. 9).

efgzjeclntvehhuhizavdtqx5si.png
Рис. 9 — Файл «main.js» в среде «VSC»

Что мы видим на рис. 9? Это слева рабочая область нашего приложения, а справа средства отладки приложения.

Теперь создадим первоначальную разметку в файле «index.html». Для чего в «VSC» делаем следующие: открываем файл «index.html»=> вводим »!» => и жмем на «Enter»=>, а дальше магия и следующий результат:




    
    
    Document


    














Ну и как в лучших традициях написания кода между тегами » вставим текст «Hello world!!!»




    
    
    Document


    Hello world!!!



После чего пробуем нажать опять «F5» и проверяем, что у нас все работает (рис. 10)

2gphhsrm4zmw4agdhrn_bk8puti.png
Рис. 10 — Окно «Hello world!!!»

Теперь нужно из скаченного нами архива webix.zip вытащить все содержимое папки «codebase» и перенести его в нашу папку libs (рис. 11).

Открываем архив заходим в папку codebase берем ее содержимое и переносим в паку libs.

wkkoxsxv0jhcyniaijycgopzmtm.png
Рис. 11 — Содержимое папки «libs»

После того как наполнили содержимым папку «libs». Открываем файл «renderer.js» и в нем пишем следующее:

// Подключаем модуль электрона
const { remote } = require('electron')
// Получаем указатель на окно браузера где будет производиться отображение нашего интерфейса
let WIN = remote.getCurrentWindow()
// Подключаем фреймворк webix
const webix = require('./libs/webix.min.js')
//Подключаем фреймворк JQuery
$ = require('jquery')
// Функция, в которую в качестве параметра как раз и будет передаваться наша с Вами верстка
webix.ui({
})


Далее приступаем к верстки нашего интерфейса. Для чего переходим вот сюда designer.webix.com/welcome жмем на кнопку «Quick Start» и вперед к верстке интерфейса. например такого какой показан на рисунке 12.

w5anxpn3zzqk3dzxndywfjlywhg.png
Рис. 12 — Верстка интерфейса в Web конструкторе Webix

Верстка, показанная на рисунке 12 очень проста, и заключается в перетаскивании мышкой нужного элемента в рабочую область конструктора. Правая часть конструктора предназначена для редактирования свойств элементов. Когда верстка закончена (рис. 13) необходимо ее перенести в файл renderer.js. Для чего жмем на кнопку «Code» и получаем готовую верстку в виде текста. Выделяем этот текст и копируем его.

wahzpxp5qwfuce1is_zszad8pz8.png
Рис. 13 — Преобразование верстки в текст

После чего открываем файл «renderer.js» в «VSC» и вставляем в заранее подготовленную функцию «webix.ui» скопированный текст (рис. 14).

// Подключаем модуль электрона
const { remote } = require('electron')
// Получаем указатель на окно браузера где будет производиться отображение нашего интерфейса
let WIN = remote.getCurrentWindow()
// Подключаем фреймворк webix
const webix = require('./libs/webix.min.js')
//Подключаем фреймворк JQuery
$ = require('jquery')
// Функция в которую в качестве параметра как раз и будет передаваться наша с Вами верстка
webix.ui(
    {
        "id": 1587908357897,
        "rows": [
            {
                "css": "webix_dark",
                "view": "toolbar",
                "height": 0,
                "cols": [
                    { "view": "label", "label": "Elcetron +Webix its cool!"},
                    { "label": "-", "view": "button", "height": 38, "width": 40},
                    { "label": "+", "view": "button", "height": 38, "width": 40},
                    { "label": "x", "view": "button", "height": 38, "width": 40}
                ]
            },
            {
                "width": 0,
                "height": 0,
                "cols": [
                    { "url": "demo->5ea58f0e73f4cf00126e3769", "view": "sidebar", "width": 177 },
                    {
                        "width": 0,
                        "height": 0,
                        "rows": [
                            { "template": "Hello WORLD! ", "view": "template" },
                            {
                                "url": "demo->5ea58f0e73f4cf00126e376d",
                                "type": "bar",
                                "xAxis": "#value#",
                                "yAxis": {},
                                "view": "chart"
                            }
                        ]
                    }
                ]
            }
        ]
    }
)


3aaoxwkqhvc6mgijiqpr9i14w2w.png
Рис. 14 — Добавление верстки созданной с помощью конструктора

Потерпите еще немного. Дале берем и открываем в «VSC» наш заранее подготовленный файл index.html и дописываем туда буквально три следующие строки строк: , и 
Файл index.html примет следующий вид:




    
    
    
    
    Document


    



Далее жмем «F5» и получаем наше приложение с версткой от Webix (рис. 15)

p8zvajunn50qabl1x1298f15bva.png
Рис. 15 — Рабочее окно приложения с версткой от Webix

Добавляем пару фишек


Все вроде работает. Но хотелось бы убрать не нужное нам с вами обрамление окна, которое не очень то вписывается в наш дизайн. Мы будем использовать с вами кастомное решение. Для чего открываем файл «main.js» и добавляем туда параметр frame: false при создании BrowserWindow, данный флаг убирает стандартное меню и обрамление окна. Должно получиться вот так:

const win = new BrowserWindow({
    width: 800,
    height: 600,
    frame:false,
    webPreferences: {
      nodeIntegration: true
    }
  })


Жмем на «F5» смотрим на результат без рамочного окна (рис. 16).

ddemsooixlvem_afpmivxevrzpo.png
Рис. 16 — Рабочее окно приложения с версткой от Webix

Осталось научить наше окно реагировать на событие от мышки. В начале сделаем заголовок активным, что бы за него можно было перемещать наше окно по экрану монитора. Для чего открываем файл «renderer.js» находим в нем элемент view: label и добавляем в него свойство css: «head_win» должно получиться как показано на рисунке 17.

   { "view": "label", "label": "Elcetron +Webix its cool!", css:"head_win" },
                    { "label": "-", "view": "button", "height": 38, "width": 40},
                    { "label": "+", "view": "button", "height": 38, "width": 40 },
                    { "label": "x", "view": "button", "height": 38, "width": 40}


fxr1qllo19mq8rgg3uumvcm7rsg.png
Рис. 17 — Добавление стиля к элементу view: label

Теперь необходимо собственно этот стиль прописать в файле созданном специально для этих целей. Открываем файл «style.css» и создаем следующий стиль:

.head_win {
    -webkit-app-region: drag;
}


После чего запускаем приложение «F5» и пробуем перетащить наше окно за заголовок. Должно все работать.

Напоследок наше приложение реагировать на нажатие мышкой на кнопки заголовка »-,+, x» окна. Для чего в конец файла «renderer.js» добавим следующий код:

// Закрытие окна
$$("close-bt").attachEvent("onItemClick", () => {
    const window = remote.getCurrentWindow();
    window.close();
})

// Свернуть окно
$$("min-bt").attachEvent("onItemClick", () => {
    const window = remote.getCurrentWindow();
    window.minimize();
})

// Распахнуть окно
$$("max-bt").attachEvent("onItemClick", () => {
    const window = remote.getCurrentWindow();
    if (!window.isMaximized()) {
        window.maximize();
    } else {
        window.unmaximize();
    }
})


В этом коде запись вида »$$(«max-bt»)» означает, обращение к элементу «Webix» по его «id». Поэтому необходимо для кнопок заголовка эти id прописать в файле «renderer.js», что мы и сделаем должно получиться как показано на рисунке 18:

   { "view": "label", "label": "Elcetron +Webix its cool!", css:"head_win" },
                    { "label": "-", "view": "button", "height": 38, "width": 40, id:"min-bt" },
                    { "label": "+", "view": "button", "height": 38, "width": 40, id:"max-bt" },
                    { "label": "x", "view": "button", "height": 38, "width": 40, id:"close-bt" }


ocu03dinewnvw1e5wwz7gprrpmw.png
Рис. 18 — Добавление стиля к элементу view: label

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

© Habrahabr.ru