Перейти к публикации
Форум - ComputerCraft
Zer0Galaxy

[OC] "Лёгкая" библиотека GUI

Рекомендованные сообщения

Для работы с библиотекой подключим её стандартным способом

forms=require("forms") 

Библиотека forms содержит следующие функции:

addForm() - создает новую форму.

run(form) - запускает обработку интерфейса, устанавливая активной форму form. 

stop() - прерывает обработку интерфейса.

 

Форма. Создается при помощи команды:

Form1=forms.addForm()

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

По умолчанию форма занимает всю область экрана. Изменить размеры формы можно задавая её параметры W и H:

Form1.W=31
Form1.H=7

а положение на экране - задавая параметры left и top:

Form1.left=10
Form1.top =5

Помимо W, H, left и top форма обладает такими свойствами:

border - наличие рамки 0-нет рамки; 1-одинарная рамка; 2-двойная рамка (по умолчанию - 0)

color - цвет формы (по умолчанию - 0х000000),

fontColor - цвет рамки (по умолчанию - 0xffffff).

 

Форма обладает следующими методами:

setActive() - устанавливает форму активной и перерисовывает её.

isActive() - возвращает true, если форма активна.

redraw() - принудительно перерисовывает форму, если форма активна.

addButton(left, top, caption, onClick) - добавляет на форму кнопку.

addLabel(left, top, caption) - добавляет на форму строку текста.

addEdit(left, top, onEnter) - добавляет на форму окно ввода.

addFrame(left, top, brd) - добавляет на форму рамку.

addList(left, top, onChange) - добавляет на форму список.

 

Поскольку форма является объектом, методы формы следует вызывать через двоеточие

Form1:setActive()

Все свойства и методы формы (за исключением setActive и isActive) присущи также другим компонентам интерфейса, которые я опишу позже.

  • Like 9

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Кнопка. Создается командой:

Button1=Form1:addButton(left,top,caption,onClick)

Команда создает на форме Form1 кнопку и возвращает указатель на вновь созданный объект.

Еще раз обращаю внимание: метод forms.addForm вызывается через разделитель "точка", а Form1:addButton - через "двоеточие", поскольку forms - это библиотека, а Form1 - объект.

 

Параметры вызова метода addButton:

left,top - (числа) координаты левого верхнего угла кнопки относительно объекта, которому принадлежит кнопка.

caption - (строка) надпись на кнопке.

onClick - (функция) обработчик нажатия на кнопку.

Левый щелчок мыши на кнопке вызовет функцию-обработчик. Функция-обработчик принимает один параметр - указатель на кнопку, которая была нажата. 

 

Дополнительные свойства кнопки:

W - ширина кнопки (по умолчанию - 10)

H - высота кнопки (по умолчанию - 1)

border - наличие рамки (по умолчанию - 0)

color - цвет кнопки (по умолчанию - 0x606060),

fontColor - цвет надписи и рамки (по умолчанию - 0xffffff).

visible - имеет значение false, если кнопка скрыта (по умолчанию - true)

X, Y - абсолютные координаты левого верхнего угла кнопки

 

Методы компонента:

hide() - скрывает компонент.

show() - отображает ранее скрытый компонент

isVisible() - возвращает true, если компонент не скрыт и находится на активной форме.

redraw() - принудительно перерисовывает компонент.

 

Компоненты интерфейса (кнопки, надписи и т.д.) можно создавать не только на форме, но и на других компонентах. К примеру, кнопку можно создать на рамке или надпись на кнопке. При этом дочерний объект будет перемещаться, исчезать и появляться вместе с объектом-родителем.

Изменено пользователем Zer0Galaxy
  • Like 4

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Надпись. Создается командой:



Label1=Form1:addLabel(left,top,caption)

Команда создает на форма Form1 надпись и возвращает указатель на вновь созданный объект.


 


Параметры вызова метода addLabel:


left,top - (числа) координаты левого верхнего угла надписи относительно объекта которому принадлежит надпись.


caption - (строка) собственно надпись.


 


Дополнительные свойства:


W - ширина надписи (по умолчанию равняется количеству символов в надписи). Если количество символов превышает ширину, лишние символы справа будут обрезаны.


H - высота (по умолчанию - 1)


border - наличие рамки (по умолчанию - 0)


color - цвет фона (по умолчанию - 0x000000),


fontColor - цвет шрифта (по умолчанию - 0xffffff).


visible - имеет значение false, если надпись скрыта (по умолчанию - true)


centered - если этот параметр у становить в true, надпись будет автоматически центрироваться. (По умолчанию - false) 


alignRight - если этот параметр установить в true и centered==false, надпись будет выравниваться по правому краю. (По умолчанию - false)


autoSize - если этот параметр установить в true, ширина компонента W автоматически подстраивается под самую длинную строку надписи. (По умолчанию - true). Да, да, надпись может иметь несколько строк. Разбиение на строки выполняется при помощи символа "\n".


X, Y - абсолютные координаты левого верхнего угла


 


Методы компонента (см. "кнопка")


Изменено пользователем Zer0Galaxy
  • Like 5

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Окно ввода.



Edit1=Form1:addEdit(left,top,onEnter)

Команда создает на форма Form1 окно ввода и возвращает указатель на вновь созданный объект.


Окно ввода позволяет вводить с клавиатуры текст, ограниченный одной строкой.


 


Параметры вызова метода addEdit:


left,top - (числа) координаты левого верхнего угла окна относительно объекта которому принадлежит компонент.


onEnter - (функция) обработчик окончания ввода.


Левый щелчок мыши на окне переведет компонент в режим ввода текста. Завершение ввода осуществляется нажатием клавиши Enter. После чего вызывается функция-обработчик, если она определена. Функция принимает один параметр - указатель на компонент, который ее вызвал.


 


Дополнительные свойства:


W - ширина окна (по умолчанию - 20).


H - высота (по умолчанию - 3)


text - строка текста, введенного в окно ввода.


border - наличие рамки (по умолчанию - 1)


color - цвет фона (по умолчанию - 0x000000),


fontColor - цвет текста и рамки(по умолчанию - 0xffffff).


visible - имеет значение false, если компонент скрыт (по умолчанию - true)


X, Y - абсолютные координаты левого верхнего угла


 


Методы компонента (см. "кнопка")


Изменено пользователем Zer0Galaxy
  • Like 5

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Рамка.



Frame1=Form1:addFrame(left,top,border)

Рамка не выполняет никаких действий, а просто служит элементом декора.


 


Параметры вызова метода addFrame:


left,top - (числа) координаты левого верхнего угла рамки относительно объекта которому принадлежит компонент.


border - (0, 1 или 2) по умолчанию - 1.


 


Дополнительные свойства:


W - ширина рамки (по умолчанию - 20).


H - высота (по умолчанию - 10)


color - цвет фона (по умолчанию - 0x000000),


fontColor - цвет рамки(по умолчанию - 0xffffff).


visible - имеет значение false, если компонент скрыт (по умолчанию - true)


X, Y - абсолютные координаты левого верхнего угла


 


Методы компонента (см. "кнопка")

  • Like 5

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Список.

List1=Form1:addList(left,top,onChange)

Список - визуальный компонент, способный хранить множество элементов данных различного типа, подобно таблице в Луа. Каждому элементу (item) списка ставится в соответствие строка (line), посредством которой этот элемент отображается на экране компьютера.

 

Параметры вызова метода addList:

left,top - (числа) координаты левого верхнего угла относительно объекта которому принадлежит компонент.

onChange - (функция) обработчик события, когда пользователь выбирает при помощи ЛКМ какой либо элемент списка.

 

Дополнительные свойства:

W - ширина списка (по умолчанию - 20).

H - высота (по умолчанию - 10)

border - (0, 1 или 2) рамка, по умолчанию - 2

color - цвет фона (по умолчанию - 0x000000),

fontColor - цвет шрифта и рамки(по умолчанию - 0xffffff).

selCol - цвет фона выбранной строки списка (по умолчанию -0x0000ff)

selFont - цвет шрифта выбранной строки (по умолчанию - 0xffff00)

index - номер выбранного элемента списка

items - таблица, содержащая элементы списка

lines - таблица, содержащая строки, соответствующие элементам списка

visible - имеет значение false, если компонент скрыт (по умолчанию - true)

X, Y - абсолютные координаты левого верхнего угла

 

В дополнение к методам, присущим остальным компонентам (см. "кнопка"), список имеет следующие методы:

clear() - очищает список

insert([pos,]line,item) - вставляет в список в позицию pos элемент item с соответствующей ему строкой line. Все последующие элементы сдвигаются на единицу. Если параметр pos отсутствует, вставка осуществляется в конец списка.

sort([comp]) - производит сортировку списка по условию comp. Если параметр comp задан, то он должен быть функцией, принимающей три параметра: comp(list, i, j), где list - указатель на список, а i и j - номера элементов списка. Функция comp должна возвращать true, если элементы списка i и j в результате сортировки меняются местами.  Если параметр comp не задан, то сортировка производится по строкам lines в алфавитном порядке.

 

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

Изменено пользователем Zer0Galaxy
  • Like 4

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Как со списком работать? Нихрена не понятно, ни как вставить, ни как удалить, что за элемент, если он все равно текстовый?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Как со списком работать? Нихрена не понятно, ни как вставить, ни как удалить, что за элемент, если он все равно текстовый?

Видимо, читать Вы не умеете совершенно. Кому Зер0 писал — один крип только знает.

t.insert(shownLine, index) — вставить строку index, отображающуюся под индексом index.

Получение элемента — t.index

Удаление элемента — table.remove(t.lines, "test") table.remove(t.names, "test")

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Нету у него там такого, и что за t и t.names?

Как непонятно было, так и осталось, поч элемент представлен строкой и каким-то item?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Нету у него там такого, и что за t и t.names?

Как непонятно было, так и осталось, поч элемент представлен строкой и каким-то item?

Если Вы чайник и/или не умеете читать — пожалуйста, уйдите.

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

 

 

Ты что-то говорил про TextEditor, он есть?

Да. Я совместил его с компонентом Edit. Если полю text компонента присвоить значение string, мы будем иметь однострочный редактор. Завершение редактирования осуществляется клавишей Enter.

Если размеры компонента сделать побольше, а полю text присвоить значение table, получим многострочный редактор. Клавиша Enter будет вставлять новую строку, а выход из редактирования - клавишей F10.

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Как со списком работать? Нихрена не понятно, ни как вставить, ни как удалить, что за элемент, если он все равно текстовый?

Список это компонент, напоминающий lua-таблицу. Только визуализированный, т.е. имеющий некое представление на экране компьютера. Как и таблица, список может хранить элементы всех доступных в луа типов данных - числа, строки, таблицы, функции. Только, в отличии от таблицы, каждый элемент списка помимо собственно данных имеет строку при помощи которой данный элемент отображается.

Вставляются элементы в список при помощи метода insert. Методу insert необходимо передать три параметра:

 - числовой - позицию, в которую вставляется элемент (при этом все последующие элементы сдвинутся);

 - строковый - имя, под которым данный элемент будет отображаться;

 - произвольный тип - собственно элемент списка.

Если позиция вставляемого элемента пропущена, элемент будет вставлен в конец списка.

Пример заполнения списка разными типами данных:

function hello()
  print("Hello, world!")
end

List1=Form1:addList(5,5) -- создаем список
List1:insert("число",42) -- заполняем список
List1:insert("строка","string")
List1:insert("таблица",{1,2,3})
List1:insert("функция",hello)

Удаление данных из списка поэлементно не предусмотрено. Список очищается целиком при помощи метода clear

 

 

 

Если Вы чайник и/или не умеете читать — пожалуйста, уйдите.

Ну зачем же сразу так?

  • Like 2

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Сделал расширение для либы:

------------------Menu------------------
local TMenu=setmetatable({W=20, H=10, selColor=0x0000ff, sfColor=0xffff00,
  type=function() return "List" end},TComponent)
TList.__index=TList
 
function TMenu:paint()
gpu.setForeground(self.sfColor)
gpu.setBackground(self.selColor)
local items=self.items
local y=self.top-1
local x=self.left
for i=1,#items do
gpu.set(x,y+i,items[i].text)

end
end
 
function TMenu:touch(x, y, btn, user)
self:hide()
	self.items[y].func()
end
 
function TComponent:addMenu(left, top,items)
if(self.type()=="Button")then
  local obj={left=left, top=top, items=items}
  self:makeChild(obj)
  return setmetatable(obj,TMenu)
  end
end

В результате тестирования: не находит метод TComponent:addMenu. В чем проблема? Компонент делал по образцу из TList.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Сделал расширение для либы:

...

В результате тестирования: не находит метод TComponent:addMenu. В чем проблема? Компонент делал по образцу из TList.

Может быть проблема в этом?

TList.__index=TList  -- а должно быть TMenu.__index=TMenu

А что это за компонент Menu? Что он должен делать?

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Это разворачивающееся меню, да, это была причина, но я ее заметил не сразу и исправил "не глядя", а кроме этого переместил объявление в начало, и думал ,что каким-то макаром это влияет))

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Сделал библиотеку внешне-расширяемой: создаем файлы в папке /lib/formsparts/ в них регистрируем новые компоненты обычным образом.http://pastebin.com/8nTiPLHc

Пример расширения: http://pastebin.com/VDd8eTdg

Буду позже добавлять различные расширения.

 

Добавил функционал выборочной загрузки расширений: файла, имена которых оканчиваются на "-" не будут загружаться.

Изменено пользователем SergOmarov

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Получается, уже существующие компоненты библиотеки можно разложить по разным файлам?

 

А зачем эти переменные делать глобальными?

_G.forms=forms
_G.TComponent=TComponent
_G.gpu=gpu

Что бы добавить новый компонент, создаешь файл в папке /lib/formsparts/ и перегружаешь комп. Кто будет добавлять компоненты динамически?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Хорошая идея, но я ее решаю по-другому: у меня есть функция require2, перегружающая библиотеку еще раз) Ее легко сделать самому, продублировав стандартную require и убрав проверку на загруженность...

Переменные в глобал ,чтобы регистрация компонента не отличалась от внутренней.

Изменено пользователем SergOmarov

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Если нужна удобная модульность — можете подождать и узерть мой аналог формс, с удобной модульностью. Собственно, я либу уже написал, дело в том что надо напитсать модули (чекбоксы всякие, поля для ввода, списки, итд)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

В библиотеку forms (и конечно же в редактор FormsMaker) добавлены два невизуальных компонента - событие и таймер. В редакторе они видны, что позволяет редактировать их свойства.


 


Событие. Создается командой:



Event1=Form1:addEvent(eventName, onEvent)

При возникновении в системе события с именем eventName будет вызвана функция-обработчик onEvent. Как видите, компонент событие аналогичен слушателю, создаваемому функцией event.listen, с той разницей, что компонент работает только в пределах создавшей его программы, а слушатель продолжит работу и после её завершения.


 


Параметры вызова метода addEvent:


eventName - (строка) имя обрабатываемого события. Если задать пустую строку, компонент будет обрабатывать все возникающие события.


onEvent - (функция) обработчик события, принимает параметры, передаваемые событием. 


 


Таймер. Создается командой:



Timer1=Form1:addTimer(interval, onTime)

Вызывает функцию onTime с заданным интервалом.


 


Параметры вызова метода addTimer:


interval - (число) период работы таймера в секундах.


onTime - (функция) обработчик события


 


Методы компонентов "событие" и "таймер":


stop() - приостанавливает работу компонента.


run() - возобновляет работу


 


  • Like 4

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Зеро, я улучшил компонент Menu(теперь посторонний клик вне области раскрытого меню закрывает его), но это потребовала нескольких серьезных изменений, и в целях оптимизации я перенес его из модуля в саму библиотеку. Можешь использовать мой вариант для последующих обнов?

http://pastebin.com/VNxmmkDU

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Есть еще какой-то LavelingFrame. Это что?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Есть еще какой-то LavelingFrame. Это что?

 

Не работающий(пока) я его там оставил случайно, его скорее надо выделить в модуль и поставлять с пакетом моей программы(для нее его и делал).

 

 

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

Menu - раскрывающееся меню, как в Windows

При создании передается таблица, содержащая итемы по структуре: {{[1]=<name>,[2]=function()end},...}

При клике по пункту <name> вызывается соответствующая функция, при клике вне меню - меню закрывается. Нельзя открыть больше 1 меню.

Изменено пользователем SergOmarov

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Форма не выводит знаки поверх себя, кроме своих частей

http://pastebin.com/FDtAVd6j

Создавать формы и компоненты следует до запуска функции run, а не по нажатию кнопки. Попробуй так:

 

 

local wce = require("WCE")
local term = require("term")
local forms = require("forms")
local event = require("event")
local buf = require("doubleBuffering")
local component = require("component")
gpu = component.gpu
 
w, h = gpu.getResolution()
------functions-------
local function exit()
  term.clear()
  forms.stop() --останавливаем выполнение среды
end

local function startgame()
  term.clear() -- этот clear можно не делать. Экран всё равно перетрется формой
  GameForm:setActive() --Делаем активной форму игры
  -- печатаем что надо
  for i=1,w do
    wce.PrintHere(i, h, "█")
  end
 -- buf.line(1, h-10, w, h-10, 0xa9a9a9, 0xa9a9ff, "█")
  buf.draw()
end

-- Создаем форму меню
  MenuForm=forms.addForm()
  MenuForm.border=1
  ButtonExit=MenuForm:addButton(w/2, h-10, "Exit", exit)
  ButtonStart=MenuForm:addButton(w/2, h-12, "Start", startgame) --по нажатию этой кнопки активной станет GameForm
-- Создаем форму игры
  GameForm=forms.addForm()
  --по нажатию этой кнопки активной станет MenuForm
  ButtonExitG=GameForm:addButton(w-10, h-1, "Exit", function() MenuForm:setActive() end)
  GameForm.border=1
--Запускаем среду на выполнение
  forms.run(MenuForm)
 

 

 

Изменено пользователем Zer0Galaxy

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Господа люди умные, подскажите смертному простому косяк его
в зачатке программы при нажатии на кнопки изменяется переменная en
эту переменную выводит Label1
дабы выводил он верно, к каждой кнопке дополнительно вывесил Label1:redraw()
но... все еще выводит 0
где же тут косяк ? не заметил очевидную опечатку или не так понял синтаксис методов ?

Осторожно! Крайняя упоротость!

 

 

require("component").gpu.setResolution(60,50)
forms=require("forms")
forms.ignoreAll()

Form1=forms.addForm()
Form1.color=12566463
Form1.border=1

en = 0

function Button1onClick(self, user)
 en = en - 1000000
 Label1:redraw()
end

Button1=Form1:addButton(13,12,"-1M",Button1onClick)
Button1.color=7217965

function Button2onClick(self, user)
 en = en - 100000
 Label1:redraw()
end

Button2=Form1:addButton(13,14,"-100К",Button2onClick)
Button2.color=7217965

function Button3onClick(self, user)
 en = en - 10000
 Label1:redraw()
end

Button3=Form1:addButton(13,16,"-10К",Button3onClick)
Button3.color=7217965

Label1=Form1:addLabel(24,14,en)
Label1.centered=true
Label1.color=984582
Label1.autoSize=false
Label1.fontColor=12779488
Label1.W=10

function Button4onClick(self, user)
 en = en + 1000000
 Label1:redraw()
end

Button4=Form1:addButton(35,12,"+1М",Button4onClick)
Button4.color=8101979

function Button5onClick(self, user)
 en = en + 100000
 Label1:redraw()
end

Button5=Form1:addButton(35,14,"+100к",Button5onClick)
Button5.color=8101979

function Button6onClick(self, user)
 en = en + 10000
 Label1:redraw()
end

Button6=Form1:addButton(35,16,"+10К",Button6onClick)
Button6.color=8101979

Label2=Form1:addLabel(10,9,"Выберите количество покупаемой энергии")
Label2.color=10395294
Label2.fontColor=0
Label2.W=38
Label2.border=4

Button7=Form1:addButton(24,19,"Оплатить")
Button7.fontColor=0
Button7.color=14329120

Label3=Form1:addLabel(10,24,"Проведите смарт-картой по считывателю")
Label3.color=10395294
Label3.fontColor=0
Label3.W=37

Label4=Form1:addLabel(26,26,"<<<<<<")
Label4.color=10395294
Label4.fontColor=0
Label4.W=6

Label5=Form1:addLabel(14,33,"Количество энергии в хранилище:")
Label5.color=10395294
Label5.fontColor=0
Label5.W=31

Label6=Form1:addLabel(24,36,"Label6")
Label6.centered=true
Label6.color=8060927
Label6.autoSize=false
Label6.fontColor=0
Label6.W=10
Label6.alignRight=true

forms.run(Form1)

 

 

Изменено пользователем _Star_Craft_

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Думаю, в каждую процедуру ButtonХonClick неплохо бы добавить фразу:

Label1.caption=en
  • Like 2

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас

×