This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
AmandaC's profile picture

[ac-get repo] Project Veek! GUI toolkit and support libraries for ComputerCraft

Started by AmandaC, 23 March 2014 - 07:42 PM
AmandaC #1
Posted 23 March 2014 - 08:42 PM
Project Veek
Project Veek is a series of libraries to make making graphical programs easier
in ComputerCraft. It consists of the following libraries:

  • lib-agui – Graphical GUI toolkit
  • agui-images – Image loading library.
  • lib-canvas – Canvas API
  • lib-thread – Multi-"threading" API
  • lib-event – Event processing and distribution API
  • lib-kidven – What allows you to make the objects themselves, and provides the inheritence and such wanted.
You can use Veek by installing it's repo with the following command:
> ac-get run-manifest https://raw.github.com/AmandaCameron/cc-veek/master/install.manifest

This will install the repo to your ac-get instalation.


Sauce?
The source code for this project can be found on My GitHub


Screenshots?


More to come


Docs?
The Docs are included below, for your viewing pleasure.



kaxuikaxui is a graphical package manager for ac-get. It features a tabbed interface which you can navigate with pageup/pagedown. There are three main panes "Available", "Installed", and "Settings" – To use this program you need an ac-get install that is up to date.

lib-aguilib-agui is a "GUI" toolkit for computercraft. It is backed by my lib-kidven for objects and lib-canvas for buffers to draw the elements under. The app itself is housed under an agui-app agui-object, which handles the event pump and the thread pool for your app. Every app should have a :main() call in it to kick off the thread pool and event pump.

The event pump is hooked into by using the :subscribe() call on the agui-app object, it also allows you to fire events with :trigger() These functions are actually provided by lib-event and as such are available to any event-pool sub-class.


Basic Widgets
  • agui-widget – Basic widget, every GUI widget descends from this at some point along the heigharchy.
  • agui-container – Basic container widget, handles storage of other widgets and drawing of them.

Input Widgets
  • agui-button – Clickable button, fires an 'gui.button.pressed' event when it's triggered.
  • agui-checkbox – Toggle box with a label. Fires a 'gui.input.changed' event when toggled.
  • agui-input – Text input box, fires a 'gui.input.changed' event when text inside it changes.
  • agui-list – Displays a list list-item widgets, fires a 'gui.list.changes' event when the selection is changed.

Display Widgets
  • agui-split-pane – Shows a common side-bar pattern for two widgets.
  • agui-tab-bar – Shows a tab bar that allows you to change tabs, each tab can contain a single widget.
  • agui-window – A window that is bound inside the app's display canvas
  • agui-virt-seperator – A Vertical seperator.
  • agui-horiz-seperator – A horizontal seperator.
  • agui-textbox – Multi-line auto-wrapping textbox widget, showing plaintext stuff.
  • agui-label – Shows a single-line bit of text, ellipsising it if nessary.
  • agui-search – A search bar widget, a combonation of a agui-input and an agui-list
  • agui-progress-bar – Progress bar! Takes a 0-1 number and shows a percentage!

Notes for Users
  • In version 9 of lib-agui everything was changed to use a agui- prefix. As a result, old programs will break.
Documentationagui-app Object.
The agui-app object is the central event pump and method of interaction for an agui app. It also handles the drawing of the GUI widgets, from the top-level object.

  • Methods
    • :add(widget) – Adds widget to the top-level GUI of the main window.
    • :remove(widget) – Rmeoves the given widget from the top-level GUI of the main window.
    • :select(widget) – Selects the given child widget of the top-level.
    • :new_window(title, width, height) – Creates a window, as per the term.newWindow() api, falling back to an agui-window object in the top-level
    • :active_window() – Returns the active window.
    • :load_theme(file) – Loads the given AGUI theme file.
    • :main() – This fires off the event pump. You are expected to call this to start your app.
    • :quit() – Kills the event pump, closing your app.
  • Fields
    • main_window – The main agui-app-window object, representing the main window for the screen.
    • pool – The Thread Pool that agui maintains. see lib-thread for docs on this object.
  • Events
    • window.resize windowid – Called when a window is resized, can be the main window or a child window, the windowid paramater will tell you.

Examples?
For examples on using this, please look in the agui-demos package.




agui-button
agui-button is a simple button widget. It's a agui-label subclass, and accepts the same input.

  • Constructor
    • new('agui-button', x, y, text, [width])
  • Methods
    • None
  • Events
    • gui.button.pressed – Called when the button is activated.



agui-checkbox
agui-checkbox is a checkbox input widget. It inherits from agui-input and it's value is stored there.

  • Constructor
    • new('agui-checkbox', x, y, text, [width])
  • Methods
    • set_value(value) – Sets the given value.
  • Events
    • gui.input.changed value – Called when the value changes.



agui-conteiner
agui-container is the base class for containers, that contain other agui-widget instances.

  • Constructor
    • new('agui-container', x, y, width, height)
  • Methods
    • :add(widget) – Adds the given agui-widget instance to this container.
    • :remove(widget) – Removes the given agui-widget instance from this container.
    • :select(widget) – Selects the given agui-widget instance.
    • :getfocused() – Returns the given focused _aguiwidget_ instance, or nil if nothing is selected.
  • Fields
    • No Public fields.



agui-input
agui-input is a basic text-input widget.

  • Constructor
    • new('gui-input', x, y, width)
  • Methods
    • None
  • Fields
    • placeholder – If non-nil, this will be written instead of the input text.
    • value – The input's value.
  • Events
    • gui.input.changed value – Called on the value changing.



agui-label
agui-label is a widget that is used to display a small set of text, compacted onto a single line.

  • Constructor
    • new('agui-label', x, y, text, [width])
  • Methods
    • No Public Methods



agui-layout Object
The agui-layout object is an anchor-based layout engine for lib-agui. You can use this to make your containers resize and move their contents when they are resized.

  • Constructor
    • new('agui-layout', container) – The container we are to wrap.
  • Methods
    • :resize(width, height) – Resizes the container then re-flows the content.
    • :reflow() – Reflows the content.
    • :addanchor(widget, side, otherside, other, dist) – See below for details.
    • :add(widget) – Adds a widget to the container THIS MUST BE USED INSTEAD OF container:add()
    • :remove(widget) – Removes a widget from the container THIS MUST BE USED INSTEEAD OF container:remove()

Anchors?
Anchors are made up of 5 components, all passed to add_anchor().

  • widget – The widget the anchor is attached to.
  • side – The side of the widget the anchor acts on.
  • other_side – The side of the other object it acts on
  • other – The other widget to act on, or -1 for the parent container.
  • dist – The distance to work on.

Sides?
Sides can be one of: top, bottom, left, right – and for other_side, you have the additional benifit of a middle option. That middle option will make the widget get aligned with the middle of the other widget, or to get aligned with the middle of the parent container.

right and bottom affect the widget's size, top and left affect the widget's position.




agui-list-item
agui-list-item is a widget that exists inside an agui-list object. It only recieves one callback from the agui-list parent, though.

  • Constructor
    • new('agui-list-item', text)
  • Callbacks
    • :draw(canvas) – Draw the list item's stuff.



agui-list
agui-list is a simple thing that is meant to hold agui-list-item instances, as well as their sub-classes.

  • Constructor
    • new('agui-list', x, y, width, height)
  • Methods
    • :add(item, [pos]) – Adds the given list item.
    • :clear() – Clears the list's contents.
    • :remove(index) – Removes the given index.
  • Events
    • gui.list.changed currentindex, currentitem – Fired when the list's selection changes.



agui-menu
agui-menu is a menu widget for agui-based apps. It operates by getting passed an agui-container on creation. It can also be given an agui-app instance, or an agui-app-window instance.

  • Methods
    • :add(label, callback) – Adds an option with the given label and callback function.
    • :add_seperator() – Adds a seperator
    • :clear() – Clears the menu.
    • :show(x, y) – Shows the given menu in the given place.
    • :hide() – Hides the menu
  • Events
    • None



agui-progress-bar
agui-progress-bar is a progress bar widget now built into lib-agui. It was previously housed in kaxui, but has been moved out for more general-purpose useage.

  • Constructors
    • new('agui-progress-bar', x, y, width) – Creates a new progress bar at the given x, y and width.
  • Methods
    • :set_format(fmt) – Sets the format for the progress text. %d will be replaced with the 0-100 percentage value.
    • :set_progress(prog) – Sets the current progress. Must be between 0 and 1, for 0 to 100%.
    • :set_indetermenate(ind) – Sets if the progress is currently indetermenate.
  • Fields
    • No Public Fields.



agui-search
This is a simple query-and-results compound widget.

  • Constructor
    • new('agui-search', width, height)
  • Methods
    • None
  • Fields
    • results – The results list.
    • input_box – The input widget.
  • Events
    • gui.search.input – Fired when the input changes. This also clears the results box.
    • gui.search.selected – Fired when a result is selected with the enter key.



agui-horiz-seperator and agui-vert-seperator
This is a simple seperation widget, meant for visually splitting off your UIs.

  • Constructor
    • new('agui-vert-seperator', x, y, height)
    • new('agui-horiz-sperator', x, y, width)
  • Methods
    • None



agui-split-pane
agui-split-pane is an AGUI widget that splits the screen into two, unevenly sided parts. The left part is smaller than the right. The Left part is for
the side-bar actions. if you are on a pocket computer, the side-bar will be hidden completely, but can be revieled by dragging from the left-most character
on the screen. This allows you to have maximum screen realestate.

  • Constructors
    • new('agui-split-pane', sidebar, mainview) – Constructs a new agui-split-pane object with the given side-bar and main views.
  • Methods
    • :resize(w, h) – Resizes the widget, as per agui-widget.
  • Properties
    • .min_pos – The minimum size the side-bar can be. If it's 0.
    • .max_pos – The maximum size the side-bar can be.
    • .position – The current size of the side-bar



agui-tab-bar
agui-tab-bar is a tab-bar widget. It contains several tabs, and each tab contains a single widget.

  • Constructor
    • new('agui-tab-bar', x, y, width, height)
  • Methods
    • :add_tab(label, contents) – Adds the given contents as a tab with the given label.
    • :select_tab(name) – Selects the tab with the given label.



agui-textbox
agui-textbox is a multi-line textbox widget for displaying large quantities of text.

  • Constructor
    • new('agui-textbox', x, y, width, height, [text])
  • Methods
    • set_text(new) – Sets the given text for displaying.
  • Fields
    • text – The given text.



agui-widget
agui-widget is the base widget for all agui widgets, it's mostly an interface for other apps, but does provide some helper functions to help widget developers.

  • Constructor
    • new('agui-widget', x, y, width, height)
  • Methods
    • :add_flag(flag) – Add a flag to the widget.
    • :has_flag(flag) – Returns true if the widget has the given flag.
    • :trigger(evt, …) – Triggers an event in the app's GUI pump.
    • :set_enabled(enabled) – Enable/disables the given widget.
    • :resize(width, height) – Resizes the given widget, handling the nessary magic for this.
    • :move(x, y) – Moves the widget to the given x and y
  • Callbacks
    • :focus() – Called when the widget is focused.
    • :blur() – Calls when the widget is un-focused.
    • :char© – coorsponds to the char event in the main event pump, assuming your widget is focused.
    • :key(keycode) – key event.
    • :clicked(x, y, btn) – Mouse clicks.
    • :dragged(xdelta, ydelta, btn) – Mouse drags, in delta.
    • :scroll(x, y, direction) – Mouse scrolls.
    • :draw(canvas) – You should do your drawing here, you're given a lib-canvas canvas object.
  • Fields
    • id – The given widget's ID.
    • x, y – Position
    • width, height – Size
    • main – The agui-app object for this app.
All other fields should be considered private, and not directly manupulated.


Events
The :trigger() method is used hevially in the base widgets. It also prefixes the widget's ID before the arguments it's passed, so all the events in agui-widget sub-classes are expected to have an id paramater before them.




agui-window
agui-window is a in-screen window. If you want to add a secondary window outside the main app's window in supported Shells, please see agui-app:new_window() instead.

  • Constructor
    • new('agui-window', title, width, height)
  • Methods
    • agui-container methods apply.
  • Fields
    • title – The window's title.
    • flags – The window's flags, see below for details.
  • Events
    • gui.window.closed – Fired when the close control is used.
    • gui.window.minimised – Fired when the minimise control is used.
    • gui.window.maximised – Fired when the maximised control is used.
    • gui.window.resized – Called when the window is resized.

Flags
The flags field is a table that contains some of the following attributes:

  • closable – Should be true/present if the window should have a close control
  • minimisable – Should be true/present if the window should have a minimise control.
  • maximisable – Should be present if the window is maximisable ( Requires: resizable )
  • resizable – Should be present if the window is resizable


lib-canvaslib-canvas is a self-contained OO-like buffer and drawing library. It's buffer features an optimised system for handling the data contents, and allows colours to be used. The Primary function of the library is canvas.new(term, lookup, width, height, buffered) – Buffered defaults to false, but the rest are required.


Canvas Object
The canvas object features several functions, listed below.

  • :move(x, y) – Moves to the given x and y.
  • :set_fg(colour) – Sets the forground to the given colour, which will be determined through the lookup paramater you passed in the constructor.
  • :set_bg(colour) – Same as set_fg but for the background.
  • :write(text) – Writes text to the screen or the buffer.
  • :clear() – clears the screen or buffer.
  • :sub(x, y, w, h) – Cuts out a sub-section of the screen or buffer. Returns the newly-created Canvas object.
  • :as_redirect(x, y, w, h) – like :sub() but returns a term.redirect capable object.
  • :set_cursor(x, y, blinking) – Sets the final on-screen position of the cursor, and wether it should be blinking.

lib-kidvenlib-kidven is an object library, originally written for agui-shell, and has since been ripped out for general-purpose use. It exposes the following functions, outlined below.

  • kidven.new(class, …) – Creates a new instance of class, passing it's :init() method the given arguments.
  • kidven.register(name, object, parent-name) – Registers a new class with the given name, object, and optional parent.
  • kidven.load(envname, objectname, file_name, env) – Registers a new class from the given kidven class file, and the optional environment passed in.

Kidven Object File?
Kidven's Object File is just a normal lua file with a table pre-defined (passed by envname). The parent for this class is discovered by the _parent variable you set in the file. The optional _env paramater passed to kidven.load will define the additional environments around for this file. For an example, look at the lib/object.lua (in-game: __LIB__/kidven/object) file, which implements the base object class for all kidven objects.


Example Code?
Ok, this is an example counter object, you'd place this somewhere then call kidven.load("Object", "counter", "path/to/file"), then you could do kidven.new("counter", 1) to initalise a new one.


_parent = "object"

function Object:init(count)
    self.count = count or 0
end

funciton Object:set_count(count)
    self.count = count
end

function Object:increment()
    self.count = self.count + 1
end

lib-threadlib-thread is a lib-kidven based thread pool system. while it can not provide forced multitasking, it does make coroutines much prettier than the parallel API allows.


Thread Object
  • Constructor
    • kidven.new('thread-pool')
  • Methods
    • :new(func, handler) – Adds a new thread, running func, with the given handler.
    • :stop() – Stops the thread pool.
    • :main() – Runs the thread pool This blocks until the threads are all finished, or :stop() is called

Handlers
Threads may be given a special handler table, that is providing various callbacks to the running app. The following callbacks are available.

  • :created() – Called after :new(), when the thread is initalised into the loop.
  • :error(err) – Called when the thread errors.
  • :die() – Called when the thread ends.
Edited on 29 May 2014 - 06:37 PM
AmandaC #2
Posted 17 April 2014 - 03:07 AM
New Update!

Greetings children! I've pushed a new update to the repo that does a whole bunch of changes. They're mostly documented in the lib-agui history.txt, but to summerise:

  • New Library! agui-images – Allows the loading and displaying of images. This can also be expanded with new file formats easily.
  • Progress Bar! I've ripped the progress bar object out of kaxui and made it into a default widget!
  • Split Panes! Now you can have an easy-to-do side-bar panel in your application, that will respond sanely to a pocket computer.
  • Whole bunch of new colours! I've changed the colours of the default widgets, to make them less eye-bleedy – Comments are welcome!
Agoldfish #3
Posted 18 April 2014 - 01:20 AM
Greetings children!
Who ya callin children? :P/>
AmandaC #4
Posted 21 May 2014 - 06:19 PM
New Update!
Greetings! I've just pushed another new update to the master branch of Project Veek. This enhances the normal computer optimisations, such as drawing things around buttons to make it more clear what they are, as well as their selected status. As a result, buttons should now be at least 3 in width. In a future date, the default button width will be changed from #text to #text + 2 – so please make sure your apps are accommodating of this. Additionally, I've added npaintpro's nft support to the agui-images library, as well as re-worked it so you can pass it a file's contents as a string.

There's still some work to be done, for instance, the Kaxui package manager does not currently work on a non-colour device. However this will be sorted at a later date. (You're welcome to help, too!)

Thanks for your time, and have a nice day/night/what-have-you!
marceloclp #5
Posted 29 May 2014 - 07:16 PM
Damn it… I was working on my graphic API, but if there is a better one, there is no reason to work on it anymore :(/>

But anyways, can you post some pictures of what your libraries can do?
AmandaC #6
Posted 29 May 2014 - 08:38 PM
There's an application included in the repos called Kaxui (ac-get install kaxui) that is a graphical front-end for ac-get using Project Veek to power it. I've just pushed an update to the repo that brings Kaxui up to modern Veek coding and UI utilisation, as well as fixes a few bugs in lib-canvas.

I also added a screenshot of Kaxui to the OP.
Edited on 29 May 2014 - 06:38 PM