Definition.dcl 10.7 KB
Newer Older
1 2 3
definition module iTasks.UI.Definition
/**
* This module provides an abstract representation of user interfaces.
4 5 6 7
*
* It is the interface between UI's as specified by tasks and the Web-based UI framework that
* renders the task UI's in a web browser.
* 
8
* This representation seeks a middle ground between being fine grained enough
9
* to describe rich user interfaces and being abstract enough to leave rendering details to the client framework.
10
*/
11
from Text.GenJSON import :: JSONNode
12 13
from Data.Maybe import :: Maybe
from Data.Functor import class Functor
14
from iTasks.Internal.Task	import :: TaskId
15 16
from Text.HTML			import :: HtmlTag
from Data.Map			import :: Map
17
from iTasks.WF.Combinators.Core import :: Action
18

19
from iTasks.WF.Definition import class iTask
20 21
from iTasks.Internal.Generic.Visualization	import generic gText, :: TextFormat(..)
from iTasks.Internal.Generic.Defaults			import generic gDefault
Steffen Michels's avatar
Steffen Michels committed
22
from iTasks.UI.Editor import :: Editor, :: EditState
23

24
from iTasks.UI.Editor.Generic import generic gEditor
25 26
from Text.GenJSON import generic JSONEncode, generic JSONDecode, :: JSONNode
from Data.GenEq import generic gEq
27 28

//Provide generic instances for all UI definitions
29
derive class iTask UI, UIType
30
derive class iTask UISize, UIBound, UIDirection, UIVAlign, UIHAlign, UISide, UIWindowType
31
derive class iTask UITreeNode
32

33 34
//Representation of a collection of changes that need to be applied to an existing UI
:: UIChange
35 36 37
	= NoChange                                           //No changes are needed
	| ReplaceUI !UI                                      //Replace the entire UI with a new version
	| ChangeUI [UIAttributeChange] [(Int,UIChildChange)] //Change the current UI and/or its children
38

Bas Lijnse's avatar
Bas Lijnse committed
39
:: UIAttributeChange = SetAttribute !String !JSONNode  //A change to a user interface attribute
40
					 | DelAttribute !String            //Remove an attribute
Bas Lijnse's avatar
Bas Lijnse committed
41 42 43
:: UIChildChange 	 = ChangeChild !UIChange           //Select a sub-component and apply the change definition there
					 | RemoveChild                     //Remove the child at the given index (next children 'move down')
					 | InsertChild !UI                 //Insert a new child at the given index (next children 'move up')
44
                     | MoveChild !Int                  //Move an existing child a given index to a new index
45
                                                       //(i,MoveChild j) == [(i,RemoveChild),(j,InsertChild _)]
46

Bas Lijnse's avatar
Bas Lijnse committed
47
derive class iTask UIChange, UIAttributeChange, UIChildChange
48

49 50 51 52 53
/**
* Rendering a user interface for a composition of is a staged process in which
* the raw UI material provided by basic tasks is grouped by layout policies to reach
* a final UI definition consisting of a set of controls and a window title for the top-level application window.
*
54
* The UI type has contstructors for the various types of partial UI definitions.
55
*/
56
:: UI = UI !UIType !UIAttributes ![UI]
57

58
:: UIType
Bas Lijnse's avatar
Bas Lijnse committed
59
	// --- Intermediate nodes: (implemented in itasks-components-raw.js) ---
60
    = UIEmpty
61
	| UIAction 
Bas Lijnse's avatar
Bas Lijnse committed
62
	// Core framework components (implemented in itasks-core.js)
63
	| UIComponent     // - Component (the client-side base class)
Bas Lijnse's avatar
Bas Lijnse committed
64
	// Containers (implemented in itasks-components-container.js)
65
    | UIViewport      // - Viewport for embedding another task instance's UI (like an iframe for tasks)
66
	| UIContainer // - The base component that contains other components
Mart Lubbers's avatar
Mart Lubbers committed
67
	| UIPanel
Bas Lijnse's avatar
Bas Lijnse committed
68
	| UIWindow
69
	| UITabSet
Bas Lijnse's avatar
Bas Lijnse committed
70 71
	| UIToolBar
	| UIButtonBar
72 73
	| UIMenu
	| UIMenuSep
74 75
	| UIList
	| UIListItem
Bas Lijnse's avatar
Bas Lijnse committed
76
	| UIDebug
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
	// Display components (implemented in itasks-components-display.js)
    | UILoader        // - Temporary loader animation
	| UITextView      // - String (non-wrapping single line text with automatic escaping)
	| UIHtmlView      // - Html (formatted multi line text)
	| UIProgressBar   // - Progress (non editable progress bar)
	// Form components (implemented in itasks-components-form.js):
	| UITextField     // - Textfield (single line text field)
	| UITextArea      // - Textarea (multi-line text field)
	| UIPasswordField // - Password (single line text field that hides the text)
	| UIIntegerField  // - Integerfield (integer number field)
	| UIDecimalField  // - Decimalfield (decimal number field)
	| UIDocumentField // - Document (info + upload possibility)
	| UICheckbox      // - Checkbox (editable checkbox)
	| UISlider        // - Slider (editable slider)
	| UIButton        // - Button that sends edit events on click
	| UILabel         // - Label (non-wrapping text label, clicks focus next component)
	| UIIcon          // - Icon (information icon with tooltip text)
	// Selection components (implemented in itasks-components-selection.js)
	| UIDropdown      // - Dropdown (choice from a list of alternatives)
	| UICheckGroup    // - A group of radio buttons or checkboxes (depends on multiple attribute)
	| UIChoiceList    // - A mutually exclusive set of radio buttons 
	| UIGrid          // - Grid (selecting an item in a table)
	| UITree          // - Tree (selecting a node in a tree structure)
100
	| UITabBar        // - A tab bar (to make a selection with)
101 102
	// Data elements (implemented in itasks-core.js)
	| UIData 
103

104
:: UIAttributes 		:== Map String JSONNode
105 106
:: UIAttribute          :== (!String,!JSONNode)
:: UIAttributeKey       :== String
Bas Lijnse's avatar
Bas Lijnse committed
107 108 109 110 111 112

// Floating window
:: UIWindowType
    = FloatingWindow        //Normal movable window
    | NotificationBubble    //Fixed position info

113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
//Most components can be resized in two dimensions
:: UISize
	= ExactSize !Int
	| WrapSize
	| FlexSize

:: UIBound
	= ExactBound !Int
	| WrapBound
	
:: UIHAlign
	= AlignLeft
	| AlignCenter
	| AlignRight

:: UIVAlign
	= AlignTop
	| AlignMiddle
	| AlignBottom
	
:: UIDirection
	= Horizontal
	| Vertical
	
:: UISide
	= TopSide
	| RightSide
	| BottomSide
	| LeftSide

:: UITreeNode =
	{ text		:: !String
    , iconCls   :: !Maybe String
	, children	:: !Maybe [UITreeNode]
	, leaf		:: !Bool
	, expanded	:: !Bool
	, value		:: !Int
	}

Bas Lijnse's avatar
Bas Lijnse committed
152 153 154 155 156 157
//Common attributes:
:: Title = Title !String
:: Hint = Hint !String
:: Label = Label !String
:: Icon = Icon !String

Bas Lijnse's avatar
Bas Lijnse committed
158 159 160 161 162 163 164 165 166 167 168 169 170
//Predefined attribute names
TITLE_ATTRIBUTE			:== "title"
HINT_ATTRIBUTE			:== "hint"
HINT_TYPE_ATTRIBUTE		:== "hint-type"
HINT_TYPE_INFO 			:== "info"
HINT_TYPE_VALID 		:== "valid"
HINT_TYPE_WARNING 		:== "warning"
HINT_TYPE_INVALID 		:== "invalid"
LABEL_ATTRIBUTE			:== "label"
PREFIX_ATTRIBUTE		:== "prefix"
POSTFIX_ATTRIBUTE		:== "postfix"
ICON_ATTRIBUTE			:== "icon"

171
//Construction functions
172 173 174 175
ui   :: UIType -> UI
uic  :: UIType [UI] -> UI
uia  :: UIType UIAttributes -> UI
uiac :: UIType UIAttributes [UI] -> UI
176

177
//Predefined attribute defintions
178 179
emptyAttr         :: UIAttributes

180
optionalAttr 	  :: !Bool                                -> UIAttributes
181

182 183 184
sizeAttr          :: !UISize !UISize                      -> UIAttributes
widthAttr         :: !UISize                              -> UIAttributes
heightAttr        :: !UISize                              -> UIAttributes
185

186
hintAttr          :: !String                              -> UIAttributes
187 188 189
titleAttr         :: !String                              -> UIAttributes
iconClsAttr       :: !String                              -> UIAttributes
tooltipAttr       :: !String                              -> UIAttributes
190

191 192 193 194 195 196 197
hposAttr          :: !UIHAlign                            -> UIAttributes
vposAttr          :: !UIVAlign                            -> UIAttributes
windowTypeAttr    :: !UIWindowType                        -> UIAttributes
focusTaskIdAttr   :: !String                              -> UIAttributes
closeTaskIdAttr   :: !String                              -> UIAttributes
activeTabAttr     :: !Int                                 -> UIAttributes
valueAttr         :: !JSONNode                            -> UIAttributes
198 199
minAttr           :: !Int                                 -> UIAttributes
maxAttr           :: !Int                                 -> UIAttributes
200 201
textAttr          :: !String                              -> UIAttributes
enabledAttr       :: !Bool                                -> UIAttributes
202
multipleAttr      :: !Bool                                -> UIAttributes
203 204 205 206 207
instanceNoAttr    :: !Int                                 -> UIAttributes
instanceKeyAttr   :: !String                              -> UIAttributes
columnsAttr       :: ![String]                            -> UIAttributes
doubleClickAttr   :: !String !String                      -> UIAttributes
actionIdAttr      :: !String                              -> UIAttributes
Bas Lijnse's avatar
Bas Lijnse committed
208
editorIdAttr      :: !String                              -> UIAttributes
209
taskIdAttr        :: !String                              -> UIAttributes
Bas Lijnse's avatar
Bas Lijnse committed
210
labelAttr         :: !String                              -> UIAttributes
211
styleAttr         :: !String                              -> UIAttributes
212
classAttr         :: ![String]                            -> UIAttributes
213 214
addClassAttr      :: !String !UIAttributes                -> UIAttributes
removeClassAttr   :: !String !UIAttributes                -> UIAttributes
215
resizableAttr     :: ![UISide]                            -> UIAttributes
Mart Lubbers's avatar
Mart Lubbers committed
216 217 218
maxlengthAttr     :: !Int                                 -> UIAttributes
minlengthAttr     :: !Int                                 -> UIAttributes
boundedlengthAttr :: !Int !Int                            -> UIAttributes
219
eventTimeoutAttr  :: !(Maybe Int)                         -> UIAttributes
220 221 222

editAttrs         :: !String !String !(Maybe JSONNode)    -> UIAttributes
choiceAttrs       :: !String !String ![Int] ![JSONNode]   -> UIAttributes
223

Bas Lijnse's avatar
Bas Lijnse committed
224
//Util
225
isOptional :: !UI -> Bool	
Bas Lijnse's avatar
Bas Lijnse committed
226
stringDisplay   :: !String  -> UI
227 228 229 230 231 232 233 234 235 236 237 238

//Encoding of UI to the format sent to the client framework
class encodeUI a :: a -> JSONNode
instance encodeUI Int
instance encodeUI Real
instance encodeUI Char
instance encodeUI String
instance encodeUI Bool
instance encodeUI HtmlTag
instance encodeUI JSONNode
instance encodeUI (Maybe a) | encodeUI a
instance encodeUI [a] | encodeUI a
239
instance encodeUI UI
240 241 242 243 244 245
instance encodeUI UISize
instance encodeUI UIBound
instance encodeUI UIVAlign
instance encodeUI UIHAlign
instance encodeUI UIDirection
instance encodeUI UIWindowType
246

247 248 249
//Combine two changes that would have to be applied one after the other into a single change
mergeUIChanges :: UIChange UIChange -> UIChange

250
//Apply changes to a ui
251
applyUIChange :: !UIChange !UI -> UI
252
applyUIAttributeChange :: !UIAttributeChange !UIAttributes -> UIAttributes
253

254
//Remove all paths that lead to a NoChange node
255
compactUIChange :: UIChange -> UIChange
256 257 258 259 260 261 262 263 264 265 266 267 268

//Makes sure that all children ranging 0 to max(index) are in the list
completeChildChanges :: [(Int,UIChildChange)] -> [(Int,UIChildChange)]

//Reassigns indices from 0 upwarths to the changes in the list
reindexChildChanges :: [(Int,UIChildChange)] -> [(Int,UIChildChange)]
//Remove all childchanges that do nothing
compactChildChanges :: [(Int,UIChildChange)] -> [(Int,UIChildChange)]

//Serialize change definitions such that they can be sent to a client
encodeUIChange :: !UIChange -> JSONNode
encodeUIChanges :: ![UIChange] -> JSONNode