This section explains the common interface of UI elements.
All ui elements can be instantiated by
>>> from luban.content.<Element> import <Element>
>>> element = <Element>( prop1=value1, prop2 = value2, ...)
where <Element> should be replaced by whatever element type you are trying to instantiate from.
For example, to create a form:
>>> from luban.content.Form import Form
>>> element = Form( prop1=value1, prop2 = value2, ...)
Each UI element type has some properties, and those properties can be either set using the constructor as shown above, or just using normal python attribute-setting syntax:
>>> element.prop1 = value1
The common properties that every element type has are
A luban user interface is a hierarchy of UI elements. This hierarchy can be created step by step by creating the elements higher in the hierarchy and adding children elements using the parent’s “add” method. For example, the following code create a “document” element and a “paragraph” element and add the “paragraph” element as a child:
>>> from luban.content.Document import Document
>>> doc = Document()
>>> from luban.content.Paragraph import Paragraph
>>> p =Paragraph()
>>> doc.add(p)
For convenience, some element containers might have member methods to create subelements directly. For example, the above code piece is equivalent to:
>>> from luban.content.Document import Document
>>> doc = Document()
>>> p = doc.paragraph()
The convention for these member methods is that the signature of the member method to create a subelement is the same as that of the constructor of that subelement type. For example, to create a Paragraph instance, the constructor is:
>>> p = Paragraph(id=..., text=...)
The ‘paragraph’ method of the Document type has the same signature, and you can create a paragraph of a document by
>>> p =doc.paragraph(id=..., title=...)
Please note that elements created from factory methods of element container are automatically added into the container, and you should not use add method to add the new element to the container again.
A common method of any element is “credential”:
>>> element.credential(username=..., ticket=...)
It creates a credential and attach it to the UI element. You should only create one credential for the UI element tree you are creating. Otherwise, which of the multiple credentials you created is used is undetermined.
To sum it up, the common properties of all elements are:
The common methods are:
The common event handlers are:
In the following, UI elements are grouped into several categories. For each element type, description of what it is and its properties are presented.
Frame element is the root element of a luban user interface.When a luban application starts up, an instance of Frame elementneeds to be established.
Properties:
Factory methods for creating sub-elements:
Class information for Frame:
Simple containers can have normal elements as their contents.
Document is a simple element container. Instances of most widget types can be children of a document. A document widget has a title which can be empty.
Properties:
Event handlers:
oncollapse:event handler for event “collapse”. The “collapse” event happens when a user collapse the document. Only valid if the document is collapsable
Example:
>>> documentinstance.oncollapse = some_action
onexpand:event handler for event “expand”. The “expand” event happens when a user expand the document. Only valid if the document is collapsable
Example:
>>> documentinstance.onexpand = some_action
Factory methods for creating sub-elements:
Class information for Document:
A dialog is a simple element container that floats. In luban, all dialogs are modal; you can create non-modal windows by ‘dockable documents’, please refer to the ‘document’ element for more details. Instances of most widget types can be children of a dialog. A dialog usually has a title, and you should usually add an ‘OK’ or ‘Close’ button to close it.
Properties:
Factory methods for creating sub-elements:
Class information for Dialog:
Form is a container of form fields and a submit button.
Note: A form cannot have another form as its descendent.
Properties
Factory methods for creating sub-elements
Class information of Form:
Properties
Note that all form fields must have an ancestor that is a form for the form-submit action to work. Otherwise you need to use “onclick” handler to construct your own form-serialization and submission actions.
Class information of FormField, their common ancestor:
Properties: see Common interface for form fields
Properties: see Common interface for form fields
Properties: see Common interface for form fields
Properties: see Common interface for form fields
Properties: see Common interface for form fields
entries: enumerated list of 2-tuples. Each 2-tuple is (value, text). For example:
[(0, 'Tiger'), (1, 'Monkey'), (2, 'Lion')]
selection: int – default selection index
FormRadioBox is a group of radio buttons.
Properties: see Common interface for form fields
Properties:
An example of using some of these Form Fields is:
import luban.content
form = luban.content.form()
textarea = form.textarea(label='text area')
textfield = form.text(label='text field')
passwordfield = form.password(label='password')
selectorfield = form.selector(entries=enumerate(['first choice', 'second choice']),
selection=0)
submitbutton = form.submitbutton(label='submit')
This section contains some other basic widgets.
Example 1:
import luban.content
sometext = luban.content.paragraph(text=['text here'])
Properties:
Class information for Paragraph:
Link is clickable. When clicked, an action will be triggered.
Properties:
Class information for Link:
A button is clickable. When clicked, an action will be triggered. It can have a label and an icon.
Properties:
Class information for Button:
An image widget displays an image
Properties:
Class information for Image:
A portlet usually is a small window. It contains items that, when clicked, lead to loading of dynamic content of UI. A portlet has a title which can be empty, and its children are of type PortletItem.
Properties:
Class information for Portlet:
Properties:
Event handlers:
onselect:event handler that triggers when this portlet item is selected. usually this event handler is preferred over “onclick” event handler for this widget
Example:
>>> portletiteminstance.onselect = some_action
Class information for PortletItem:
An accordion can be used to view some mutually exclusive items. Each item (section) has a title. An accordion item (section) can be parent of luban elements such as documents, which will show up when this item was selected.
Event handlers:
onchange:event handler that triggers when a different section was selected
Example:
>>> accordioninstance.onchange = some_action
Factory methods for creating sub-elements:
Class information for Accordion:
Properties:
Factory methods for creating sub-elements:
Class information for AccordionSection:
A ‘tabs’ element is a container of ‘tab’ elements. The widget shows one tab at a time. Usually, when a tab is clicked, it shows up.
Example 1:
import luban.content
tabs = luban.content.tabs()
tabs.tab('tab1').paragraph(text=['tab1 text'])
tabs.tab('tab2').document(title='tab2')
Factory methods for creating sub-elements:
Class information for Tabs:
Properties:
Event handlers:
onselect:event handler that triggers when this tab is selected
Example:
>>> tabinstance.onselect = some_action
Factory methods for creating sub-elements:
Class information for Tab:
A ‘splitter’ splits a space into sections vertically or horizontally. The orientation of the splitter is defined by its attribute ‘orientation’.
Example 1:
# the follwoing code creates a splitter that is oriented horizontally and has 3 sections
import luban.content
splitter = luban.content.splitter(orientation='horizontal')
left = splitter.section()
middle = splitter.section()
right = splitter.section()
left.paragraph(text=['left'])
middle.paragraph(text=['middle'])
right.paragraph(text=['right'])
Properties:
Factory methods for creating sub-elements:
Class information for Splitter:
Properties:
Factory methods for creating sub-elements:
Class information for SplitSection:
A grid divides a space into cells. Widgets can be placed into a grid to achieve better control the positioning.
Example 1:
grid = luban.content.grid()
row0 = grid.row()
row0.cell().document(title='row 0, col 0: a document')
row0.cell().add(luban.content.form(title='row 0, col 1: a form'))
row1 = grid.row()
row1.cell().document(title='row 1, col 0')
row1.cell().add('row 1, col 1')
row1.cell().document(title='row 1, col 2')
row1.cell().add(luban.content.paragraph(text=['row1, col3']))
Class information for Grid:
A htmldocument widget can be used to display simple html-based content. It cannot handle complex html document with javascript, etc.
Properties:
Class information for HtmlDocument:
A ReStructuredTextDocument widget can be used to display textin ReStructuredText format.
Properties:
Class information for ReStructuredTextDocument:
A Plot2D widget displays a plot of x-y curve(s).
Example 1:
import luban.content
plot = luban.content.plot2d()
x = range(10)
y1 = x; y2 = [xi*xi for xi in x]
plot.curve(x=x, y=y1, label='curve1')
plot.curve(x=x, y=y2, label='curve2')
Properties:
Class information for Plot2D:
A CodeEditor widget can be used to edit a piece of code.
Properties:
Event handlers:
onsave:event handler that triggers when user clicks the save button of the widget
Example:
>>> codeeditorinstance.onsave = some_action
onchange:event handler that triggers when user changes the text in the widget and the widget lost focus
Example:
>>> codeeditorinstance.onchange = some_action
Class information for CodeEditor:
A ProgressBar widget is an indicator of the progress of some work. Every few seconds (defined by attribute ‘skip’), a ‘checking’ event will trigger and the event handler for the ‘checking’ event has toload the progress status and percentage from the controller, in order to update the progress bar. When the progress is 100%, a ‘finished’ event will trigger and the ‘checking’ event will not fire anymore. Before a progressbar is ‘finished’, it can be canceled and, when canceled, a ‘canceled’ event will trigger.
Properties:
Event handlers:
onchecking:Please give a tip of property onchecking
Example:
>>> progressbarinstance.onchecking = some_action
oncanceled:Please give a tip of property oncanceled
Example:
>>> progressbarinstance.oncanceled = some_action
onfinished:Please give a tip of property onfinished
Example:
>>> progressbarinstance.onfinished = some_action
Class information for ProgressBar:
A toolbar is a simple, horizontal container. Mostly it contains buttons.
Example 1:
import luban.content
toolbar = luban.content.toolbar()
b1 = toolbar.button(label='button1')
b2 = toolbar.button(label='button2')
toolbar.spacer()
b3 = toolbar.button(label='button3')
Factory methods for creating sub-elements:
Class information for Toolbar:
A newsticker widget rotates headers of news items. A news item will stay a few seconds (defined by attribute ‘delay’). A newsticker will triggers ‘refresh’ event every few moments (defined by attribute ‘refreshtime’), which can be used to retrieve a new set of news items, for example.
Properties:
Event handlers:
onrefresh:event handler that triggers at refresh event
Example:
>>> newstickerinstance.onrefresh = some_action
Class information for NewsTicker:
A TreeView is an expandable/collapsible tree containing TreeViewBranch and TreeViewLeaf objects.
Properties
Factory methods for creating sub-elements
Note: a treeview only has one root. All further branches and leaves must be under this root branch.
TreeViewBranch is a branch in a TreeView and can only be added to TreeViews or other TreeViewBranch objects.
Properties
Factory methods for creating sub-elements
TreeViewLeaf is a leaf on a TreeViewBranch. It must be added to a TreeViewBranch.
Properties: See properties of TreeViewBranch
Example usage of TreeView, TreeViewBranch, and TreeViewLeaf:
import luban.content
treeview = luban.content.treeview()
root = treeview.setRoot(label='root')
branch1 = root.branch(label='branch 1')
leaf = branch1.leaf(label='leaf')
Class information for TreeView, TreeViewBranch TreeViewLeaf:
A Table is a grid with columns of cells.
Properties:
Model describes the data model this table is used to represent. In the model you describe the available “measures” of the model by specifying their names and types and other properties using descriptors (see example below).
Properties:
A View contains several columns.
Properties:
A Column describes a column in a table, and is contained in columns in View.
Properties:
Example usage of Table:
from luban.content.table import Table, Model, View
# create a model class
class model(Model):
firstname = Model.descriptors.str(name='firstname')
lastname = Model.descriptors.str(name='lastname')
# create a view
view = View( columns = [ View.Column(label='First Name', measure='firstname'),
View.Column(label='Last Name', measure='lastname',
editable=True) ],
editable=True)
# enter data
data = [('John', 'Smith'),
('Jane', 'Doe')]
# create the table
table = Table(model=model, data=data, view=view)
MatterBuilder can be used to show configurations of atomic sytems such as crystals, molecules, or complex disordered materials.
Properties:
Class information for MatterBuilder:
Calling the methods described below returns an Action instance. This Action instance can be assigned to the ‘onclick’ attribute of an element, for example.
>>> load(actor=..., routine=..., **kwds)
actor is a string that is the name of the actor. routine is a string that is the name of the method to call in the actor.
This method must be called by a selector that selects an UI element.
>>> selector.notify(event, actor=..., routine=..., **kwds)
event is a string that is the name of the event. actor is a string that is the name of the actor. routine is a string that is the name of the method in that actor to call.
>>> select(id=...)
>>> select(element=...)
select returns the element instance as a selector, finding it by either its id, a property of the element, or the element instance (if the element python instance is available in local namespace). You can use this to select a certain element to then perform actions on it.
For example, if you had a document with name document and id ‘document1’:
import luban.content
document = luban.content.document(title='title', id='document1')
You could select this document by calling either:
select(id='document1')
or:
select(element=document)
You can then call the actions described below on the selected element (below, called ‘selector’).
>>> select(id=...).find(name=...)
“find” can find a descendent of an ancestor element given the name of the descendent. The ancestor element itself must be specified by using a selector method. The name of the descendent must be unique among all the descendents.
In the below samples, selector refers to the selected element. Calling each of the methods described below returns an Action instance. This Action instance can be assigned to the ‘onclick’ attribute of an element, for example.
This only has effects on form fields at this moment. You can enable/disable any individual form field. You can also enable/disable any element container, which will enable/disable all form fields inside the container.
>>> selector.replaceContent(newcontent)
newcontent is some element that you wish to replace the selected element with.
This replaces the selected content with newcontent.
>>> selector.append(newelement)
Add a child element, newelement, to the selected element. For example, add another text field to a form, or add another button to a document.
>>> selector.setAttr(attr1=value1, attr2=value2)
Use this to set the properties of an element. This method works for most attributes (NOT include event handlers such as onclick) of most element types. But the following are exceptions
>>> selector.getAttr(attrname)
Use this to get the value of an attribute of an element.
Currently, this action is only implemented for form field types (FormTextField, etc).
>>> selector.addClass(newclass)
>>> selector.removeClass(klass)
>>> from luban.content import createCredential
>>> action = createCredential(username=..., ticket=...)
>>> from luban.content import updateCredential
>>> action = updateCredential(username=..., ticket=...)
>>> from luban.content import removeCredential
>>> action = removeCredential()
All actions of this kind have a similar signature:
>>> selector.<elementtype>(<actiontype>, **parameters)
For example, to call “showError” on a formfield, do:
>>> selector.formfield('showError', message=...)
Here, the method name “formfield” indicates that the action is done to a form field, and the first argument “showError” indicates what action to take, and the keyword “message” specifies the argument for the action.
In the following, each section is for one element type, and actions for that element type are listed.
The actions here are good for form fields.
showError: Displays an error message. Takes a string parameter that is the message, and should be called on a selected FormField element.
Example usage:
>>> action = select(id='passwordfield').formfield('showError', message='error!')
where passwordfield is the id of a FormPasswordField, for example.
The following are good for formselectorfield.
The actions here are good for TreeView.
setRoot: set the root node.
Example usage:
>>> action = select(id='treeview').treeview('setRoot', root=...)
addBranch: add a new branch
Example usage:
>>> action = select(id='treeview').treeview('addBranch', referencenode=..., newnode=..., position=...)
- referencenode: selector of reference node
- newnode: new node
- position: options are “before”, “after”, or <index> (an integer)
- before/after: meaning the new node is before or after the reference node
- <index>: This option means that the reference node will be the parent node into which the new node will be added. The number given would be the index of the insert position among the children of the reference node
removeNode: remove a node
Example usage:
>>> action = select(id='treeview').treeview('removeNode', node=...)
- node: the node to be removed. If not given, means to remove the current selected node
selectNode: select a node
Example usage:
>>> action = select(id='treeview').treeview('selectNode', node=...)
- node: the node to be selected.
getIdentifiersForCheckedRows: get identifiers for checked rows.
Example usage:
>>> action = select(id='table').table('getIdentifiersForCheckedRows', colname='selected')
open: open the dialog
Example usage:
>>> action = select(id='dialog').open()
close: close the dialog
Example usage:
>>> action = select(id='dialog').close()
- select: select this tab
- select: select this portletitem
Here are some addtional actions.
Example usage:
from luban.content import alert warning = alert('Warning!') button.onclick = warningwhere button is a luban.content.Button, for example.
You can think of director as the “controller” in the MVC.
director.retrieveVisual(name)
loads the odb file <luban_project>/content/components/visuals/<name>.odb, and calls the method “visual” using “director” itself as the argument, and returns the result of the method call.