2010-01-07 20:21:07 +00:00
/ *
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
ox . ui . js
requires
2010-01-25 11:42:28 +00:00
jquery - 1.4 . js
2010-01-07 20:21:07 +00:00
ox . js
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
* /
// also see test.js, in demos ...
( function ( ) {
var oxui = {
defaultTheme : "classic" ,
elements : { } ,
getDimensions : function ( orientation ) {
return orientation == "horizontal" ?
[ "width" , "height" ] : [ "height" , "width" ] ;
} ,
getEdges : function ( orientation ) {
return orientation == "horizontal" ?
[ "left" , "right" , "top" , "bottom" ] :
[ "top" , "bottom" , "left" , "right" ] ;
} ,
getBarSize : function ( size ) {
var sizes = {
xsmall : 16 ,
small : 24 ,
medium : 28 ,
large : 32 ,
xlarge : 40
} ;
return sizes [ size ] ;
} ,
2010-01-25 11:42:28 +00:00
jQueryFunctions : function ( ) {
2010-01-07 20:21:07 +00:00
var functions = [ ] ,
2010-01-25 11:42:28 +00:00
$element = $ ( "<div>" ) ;
//delete $element.length;
Ox . each ( $element , function ( k , v ) {
2010-01-07 20:21:07 +00:00
if ( typeof v == "function" ) {
functions . push ( k ) ;
}
} ) ;
return functions . sort ( ) ;
} ( ) ,
path : $ ( "script[src*=ox.ui.js]" ) . attr ( "src" )
. replace ( "js/ox.ui.js" , "" ) ,
2010-02-03 12:12:21 +00:00
stack : [ ] , // fixme: used?
symbols : { // fixme: make lowercase
alt : "\u2325" ,
apple : "\uF8FF" ,
arrow _down : "\u2193" ,
arrow _left : "\u2190" ,
"arrow right" : "\u2192" ,
"arrow up" : "\u2191" ,
"backspace" : "\u232B" ,
"backup" : "\u2707" ,
"ballot" : "\u2717" ,
"black star" : "\u2605" ,
"burn" : "\u2622" ,
"caps lock" : "\u21EA" ,
"check" : "\u2713" ,
"CLEAR" : "\u2327" ,
"CLICK" : "\uF803" ,
"CLOSE" : "\u2715" ,
"COMMAND" : "\u2318" ,
"CONTROL" : "\u2303" ,
"CUT" : "\u2702" ,
"DELETE" : "\u2326" ,
"DIAMOND" : "\u25C6" ,
"EDIT" : "\uF802" ,
"EJECT" : "\u23CF" ,
"ESCAPE" : "\u238B" ,
"END" : "\u2198" ,
"ENTER" : "\u2324" ,
"FLY" : "\u2708" ,
"GEAR" : "\u2699" ,
"HOME" : "\u2196" ,
"INFO" : "\u24D8" ,
"NAVIGATE" : "\u2388" ,
"OPTION" : "\u2387" ,
"PAGE UP" : "\u21DE" ,
"PAGE DOWN" : "\u21DF" ,
"REDO" : "\u21BA" ,
"RETURN" : "\u21A9" ,
"SELECT" : "\u21D5" ,
"SHIFT" : "\u21E7" ,
"SOUND" : "\u266B" ,
"SPACE" : "\u2423" ,
"TAB" : "\u21E5" ,
"TRASH" : "\u267A" ,
"TRIANGLE DOWN" : "\u25BC" ,
"TRIANGLE LEFT" : "\u25C0" ,
triangle _right : "\u25BA" ,
"TRIANGLE UP" : "\u25B2" ,
"UNDO" : "\u21BB" ,
"VOLTAGE" : "\u26A1" ,
"WARNING" : "\u26A0" ,
"WHITE STAR" : "\u2606"
}
2010-01-07 20:21:07 +00:00
} ,
$window , $document , $body ;
$ ( function ( ) {
$window = $ ( window ) ,
$document = $ ( document ) ,
$body = $ ( "body" ) ;
Ox . theme ( oxui . defaultTheme ) ;
} )
/ *
=== === === === === === === === === === === === === === === === === === === === === === === === === =
Application
=== === === === === === === === === === === === === === === === === === === === === === === === === =
* /
/ *
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Ox . App
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
2010-01-27 12:30:00 +00:00
Ox . App = function ( ) {
/ *
options :
requestTimeout
requestType
requestURL
* /
return function ( options ) {
options = options || { } ;
var self = { } ,
that = this ;
self . options = $ . extend ( {
requestTimeout : oxui . requestTimeout ,
requestType : oxui . requestType ,
requestURL : oxui . requestURL
} , options ) ;
self . change = function ( ) {
} ;
that . launch = function ( ) {
$ . ajaxSetup ( {
timeout : self . options . requestTimeout ,
type : self . options . requestType ,
url : self . options . requestURL
} ) ;
} ;
that . options = function ( ) {
return Ox . getset ( self . options , Array . slice . call ( arguments ) , self . change , that ) ;
} ;
2010-01-31 08:03:22 +00:00
that . request = function ( action , data , callback ) {
if ( arguments . length == 2 ) {
2010-01-27 13:25:37 +00:00
callback = data ;
data = { } ;
}
return Ox . Request . send ( {
url : self . options . requestURL ,
data : {
2010-01-31 08:03:22 +00:00
action : action ,
2010-01-27 13:25:37 +00:00
data : JSON . stringify ( data )
} ,
callback : callback
} ) ;
} ;
2010-01-27 12:30:00 +00:00
return that ;
} ;
} ( ) ;
2010-01-07 20:21:07 +00:00
/ *
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Ox . Event
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2010-02-03 12:12:21 +00:00
2010-01-07 20:21:07 +00:00
naming convention for event / trigger
verb . id . namespace , i . e . verb . sourceId . targetId ( ? )
...
bind ( "keydown.shift+dot.numpad" , function ( ) {
// ...
} )
keyboard handler then would :
$ . each ( stack , function ( i , v ) {
elements [ v ] . trigger ( "keydown.shift+0.numpad" ) ;
} ) ;
and the element would implement
this . trigger ( event , data ) {
}
...
keyboard handler also triggers keydown . buffer
* /
// use dom elements / jquery instead
2010-02-03 12:12:21 +00:00
2010-01-07 20:21:07 +00:00
Ox . Event = function ( ) {
2010-02-04 08:02:23 +00:00
var $eventHandler = $ ( "<div>" ) ;
return {
bind : function ( event , callback ) {
$eventHandler . bind ( event , callback ) ;
} ,
trigger : function ( event , data ) {
$eventHandler . trigger ( event , data ) ;
} ,
unbind : function ( event ) {
$eventHandler . unbind ( event , callback ) ;
}
}
}
Ox . Event _ = function ( ) {
2010-01-07 20:21:07 +00:00
var events = { } ;
return {
// make these bind, trigger, unbind
publish : function ( event , data ) {
console . log ( "publish" , event , data ) ;
if ( events [ event ] ) {
$ . each ( events [ event ] , function ( i , v ) {
setTimeout ( function ( ) {
v ( data ) ;
} , 0 ) ;
} ) ;
}
} ,
subscribe : function ( event , callback ) {
console . log ( "subscribe" , event , callback ) ;
if ( events [ event ] ) {
events [ event ] . push ( callback ) ;
} else {
events [ event ] = [ callback ] ;
}
} ,
unsubscribe : function ( event , callback ) {
console . log ( "unsubscribe" , event , callback ) ;
$ . each ( events [ event ] , function ( i , v ) {
if ( Ox . startsWith ( callback . toString ( ) , v . toString ( ) ) ) {
events [ event ] . splice ( i , 1 ) ;
}
} ) ;
}
} ;
} ( ) ;
/ *
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Ox . Focus
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
Ox . Focus = function ( ) {
var stack = [ ] ;
return {
focus : function ( id ) {
var index = stack . indexOf ( id ) ;
if ( index > - 1 ) {
oxui . stack . splice ( i , 1 ) ;
}
oxui . stack . push ( id ) ;
} ,
blur : function ( id ) {
oxui . stack . pop ( ) ;
}
} ;
} ( ) ;
/ *
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Ox . History
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
/ *
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Ox . Keyboard
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
( function ( ) {
2010-01-25 11:42:28 +00:00
2010-01-07 20:21:07 +00:00
var buffer = "" ,
bufferTime = 0 ,
bufferTimeout = 1000 ,
keyNames = function ( ) {
return {
0 : "section" ,
8 : "backspace" ,
9 : "tab" ,
12 : "clear" ,
13 : "enter" ,
16 : "shift" ,
17 : "control" ,
18 : "alt" ,
20 : "capslock" ,
27 : "escape" ,
32 : "space" ,
33 : "pageup" ,
34 : "pagedown" ,
35 : "end" ,
36 : "home" ,
37 : "left" ,
38 : "up" ,
39 : "right" ,
40 : "down" ,
45 : "insert" ,
46 : "delete" ,
47 : "help" ,
48 : "0" ,
49 : "1" ,
50 : "2" ,
51 : "3" ,
52 : "4" ,
53 : "5" ,
54 : "6" ,
55 : "7" ,
56 : "8" ,
57 : "9" ,
65 : "A" ,
66 : "B" ,
67 : "C" ,
68 : "D" ,
69 : "E" ,
70 : "F" ,
71 : "G" ,
72 : "H" ,
73 : "I" ,
74 : "J" ,
75 : "K" ,
76 : "L" ,
77 : "M" ,
78 : "N" ,
79 : "O" ,
80 : "P" ,
81 : "Q" ,
82 : "R" ,
83 : "S" ,
84 : "T" ,
85 : "U" ,
86 : "V" ,
87 : "W" ,
88 : "X" ,
89 : "Y" ,
90 : "Z" ,
91 : "meta.left" ,
92 : "meta.right" ,
93 : "select" ,
96 : "0.numpad" ,
97 : "1.numpad" ,
98 : "2.numpad" ,
99 : "3.numpad" ,
100 : "4.numpad" ,
101 : "5.numpad" ,
102 : "6.numpad" ,
103 : "7.numpad" ,
104 : "8.numpad" ,
105 : "9.numpad" ,
106 : "asterisk.numpad" ,
107 : "plus.numpad" ,
109 : "minus.numpad" ,
108 : "enter.numpad" ,
110 : "dot.numpad" ,
111 : "slash.numpad" ,
112 : "f1" ,
113 : "f2" ,
114 : "f3" ,
115 : "f4" ,
116 : "f5" ,
117 : "f6" ,
118 : "f7" ,
119 : "f8" ,
120 : "f9" ,
121 : "f10" ,
122 : "f11" ,
123 : "f12" ,
124 : "f13" ,
125 : "f14" ,
126 : "f15" ,
127 : "f16" ,
144 : "numlock" ,
145 : "scrolllock" ,
186 : "semicolon" ,
187 : "equal" ,
188 : "comma" ,
189 : "minus" ,
190 : "dot" ,
191 : "slash" ,
192 : "backtick" ,
219 : "openbracket" ,
220 : "backslash" ,
221 : "closebracket" ,
222 : "quote"
// see dojo, for ex.
} ;
} ( ) ,
modifierNames = {
altKey : "alt" , // mac: option
ctrlKey : "control" ,
metaKey : "meta" , // mac: command
shiftKey : "shift"
} ;
return function ( ) {
document . keydown ( keydown ) ;
function keydown ( e ) {
var key = [ ] ,
2010-01-25 11:42:28 +00:00
ret = true ,
time ;
2010-01-07 20:21:07 +00:00
$ . each ( modifierNames , function ( k , v ) {
if ( e [ k ] ) {
key . push ( v ) ;
}
} ) ;
// avoid pushing modifier twice
if ( keyNames [ e . keyCode ] && keys . indexOf ( keyNames [ e . keyCode ] ) == - 1 ) {
key . push ( keyNames [ e . keyCode ] ) ;
}
key = key . join ( " " ) ;
if ( key . match ( /^[\w\d-]$|SPACE/ ) ) {
2010-01-25 11:42:28 +00:00
time = Ox . time ( ) ;
2010-01-07 20:21:07 +00:00
if ( time - bufferTime > bufferTimeout ) {
buffer = "" ;
}
buffer += key == "SPACE" ? " " : key ;
bufferTime = time ;
}
$ . each ( stack , function ( i , v ) {
// fixme: we dont get the return value!
ret = Ox . event . publish ( keyboard + Ox . toCamelCase ( key ) + "." + v ) ;
return ret ;
} ) ;
}
} ;
} ) ( ) ;
/ *
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Ox . Mouse ( ? ? )
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
2010-01-27 12:30:00 +00:00
/ *
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Ox . Request
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
Ox . Request = function ( ) {
var cache = { } ,
pending = { } ,
requests = { } ,
self = {
options : {
timeout : 15000 ,
type : "POST" ,
url : "api"
}
} ;
return {
cancel : function ( ) {
var index ;
if ( arguments . length == 0 ) {
requests = { } ;
} else if ( Ox . isFunction ( arguments [ 0 ] ) ) {
// cancel with function
$ . each ( requests , function ( id , req ) {
if ( arguments [ 0 ] ( req ) ) {
delete requests [ id ] ;
}
} )
} else {
// cancel by id
delete requests [ arguments [ 0 ] ]
}
} ,
2010-01-27 12:34:27 +00:00
emptyCache : function ( ) {
cache = { } ;
2010-01-27 12:35:37 +00:00
} ,
2010-01-27 12:34:27 +00:00
2010-01-27 12:30:00 +00:00
options : function ( options ) {
2010-01-27 12:34:27 +00:00
return Ox . getset ( self . options , options , $ . noop ( ) , this ) ;
2010-01-27 12:30:00 +00:00
} ,
send : function ( options ) {
options = $ . extend ( {
age : - 1 ,
callback : function ( ) { } ,
id : Ox . uid ( ) ,
timeout : self . options . timeout ,
type : self . options . type ,
url : self . options . url
} , options ) ;
var req = JSON . stringify ( {
url : options . url ,
data : options . data
} ) ;
2010-01-31 10:06:52 +00:00
function callback ( data ) {
2010-01-27 12:30:00 +00:00
delete requests [ options . id ] ;
2010-01-31 10:06:52 +00:00
options . callback ( data ) ;
2010-01-27 12:30:00 +00:00
}
2010-01-31 09:32:41 +00:00
function debug ( request ) {
var $iframe = $ ( "<iframe>" )
. css ( { // fixme: should go into a class
width : 768 ,
height : 384
} ) ,
$dialog = new Ox . Dialog ( {
title : "Application Error" ,
buttons : [
{
value : "Close" ,
click : function ( ) {
$dialog . close ( ) ;
}
}
] ,
width : 800 ,
height : 400
} )
. append ( $iframe )
. open ( ) ,
iframe = $iframe [ 0 ] . contentDocument || $iframe [ 0 ] . contentWindow . document ;
iframe . open ( ) ;
iframe . write ( request . responseText ) ;
iframe . close ( ) ;
}
2010-01-27 12:30:00 +00:00
function error ( request , status , error ) {
2010-01-31 10:06:52 +00:00
var data ;
2010-02-01 06:11:35 +00:00
if ( arguments . length == 1 ) {
data = arguments [ 0 ]
} else {
try {
data = JSON . parse ( request . responseText ) ;
} catch ( err ) {
data = {
status : {
code : request . status ,
text : request . statusText
}
} ;
}
2010-01-27 13:25:37 +00:00
}
2010-01-31 10:06:52 +00:00
if ( data . status . code < 500 ) {
callback ( data ) ;
} else {
2010-01-27 13:25:37 +00:00
var $dialog = new Ox . Dialog ( {
2010-01-31 09:32:41 +00:00
title : "Application Error" ,
buttons : [
{
value : "Details" ,
click : function ( ) {
$dialog . close ( function ( ) {
debug ( request ) ;
} ) ;
}
} ,
{
value : "Close" ,
click : function ( ) {
2010-01-31 10:06:52 +00:00
$dialog . close ( function ( ) {
callback ( data ) ;
} ) ;
2010-01-31 09:32:41 +00:00
}
}
] ,
width : 400 ,
height : 100
} )
2010-01-31 10:06:52 +00:00
. append ( "Sorry, we have encountered an application error while handling your request. To help us find out what went wrong, you may want to report this error to an administrator. Otherwise, please try again later." )
2010-01-31 09:32:41 +00:00
. open ( ) ;
2010-02-01 06:11:35 +00:00
// fixme: change this to Send / Don't Send
2010-01-27 13:25:37 +00:00
Ox . print ( {
request : request ,
status : status ,
error : error
} ) ;
}
2010-01-27 12:30:00 +00:00
pending [ options . id ] = false ;
}
function success ( data ) {
pending [ options . id ] = false ;
try {
data = JSON . parse ( data ) ;
2010-02-01 06:11:35 +00:00
} catch ( err ) {
error ( {
2010-01-31 09:32:41 +00:00
status : {
code : 500 ,
text : "Internal Server Error"
} ,
data : { }
2010-02-01 06:11:35 +00:00
} ) ;
return ;
2010-01-27 12:30:00 +00:00
}
cache [ req ] = {
data : data ,
time : Ox . getTime ( )
} ;
2010-01-31 10:06:52 +00:00
callback ( data ) ;
2010-01-27 12:30:00 +00:00
}
if ( pending [ options . id ] ) {
setTimeout ( function ( ) {
Ox . Request . send ( options ) ;
} , 0 ) ;
} else {
requests [ options . id ] = {
url : options . url ,
data : options . data
} ;
if ( cache [ req ] && ( options . age == - 1 || options . age > Ox . getTime ( ) - cache [ req ] . time ) ) {
setTimeout ( function ( ) {
2010-01-31 10:06:52 +00:00
callback ( cache [ req ] . data ) ;
2010-01-27 12:30:00 +00:00
} , 0 ) ;
} else {
pending [ options . id ] = true ;
$ . ajax ( {
data : options . data ,
error : error ,
success : success ,
timeout : options . timeout ,
type : options . type ,
url : options . url
} ) ;
}
}
return options . id ;
}
} ;
} ( ) ;
2010-01-07 20:21:07 +00:00
/ *
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Ox . URL
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
/ *
=== === === === === === === === === === === === === === === === === === === === === === === === === =
Core
=== === === === === === === === === === === === === === === === === === === === === === === === === =
* /
/ *
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Ox . Container
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
// fixme: wouldn't it be better to let the elements be,
// rather then $element, $content, and potentially others,
// 0, 1, 2, etc, so that append would append 0, and appendTo
// would append (length - 1)?
Ox . Container = function ( ) {
var that = new Ox . Element ( )
. addClass ( "OxContainer" ) ;
that . $content = new Ox . Element ( )
. addClass ( "OxContent" )
. appendTo ( that ) ;
return that ;
}
/ *
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Ox . Element
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
// check out http://ejohn.org/apps/learn/#36 (-#38, making fns work w/o new)
Ox . Element = function ( ) {
2010-01-25 11:42:28 +00:00
var elements = { } ;
2010-01-07 20:21:07 +00:00
return function ( options , self ) {
// construct
options = options || { } ;
self = self || { } ;
var that = this ;
// init
( function ( ) {
// allow for Ox.Widget("tagname", self)
if ( typeof options == "string" ) {
options = {
element : options
} ;
}
that . ox = Ox . version ;
that . id = Ox . uid ( ) ;
2010-01-25 11:42:28 +00:00
that . $element = $ ( "<" + ( options . element || "div" ) + "/>" , {
data : {
ox : that . id
}
} ) ;
2010-01-07 20:21:07 +00:00
elements [ that . id ] = that ;
wrapjQuery ( ) ;
} ) ( ) ;
// private
function wrapjQuery ( ) {
2010-01-25 11:42:28 +00:00
$ . each ( oxui . jQueryFunctions , function ( i , v ) {
2010-01-07 20:21:07 +00:00
that [ v ] = function ( ) {
var args = arguments ,
length = args . length ,
id , ret ;
$ . each ( args , function ( i , v ) {
// if an ox object was passed
// then pass its $element instead
// so we can do oxObj.jqFn(oxObj)
if ( v . ox ) {
args [ i ] = v . $element ;
}
} ) ;
// why does this not work?
// ret = that.$element[v].apply(this, arguments);
if ( length == 0 ) {
ret = that . $element [ v ] ( ) ;
} else if ( length == 1 ) {
ret = that . $element [ v ] ( args [ 0 ] ) ;
} else if ( length == 2 ) {
ret = that . $element [ v ] ( args [ 0 ] , args [ 1 ] ) ;
} else if ( length == 3 ) {
ret = that . $element [ v ] ( args [ 0 ] , args [ 1 ] , args [ 2 ] ) ;
} else if ( length == 4 ) {
ret = that . $element [ v ] ( args [ 0 ] , args [ 1 ] , args [ 2 ] , args [ 3 ] ) ;
}
// if the $element of an ox object was returned
// then return the ox object instead
// so we can do oxObj.jqFn().oxFn()
return ret . jquery && elements [ id = ret . data ( "ox" ) ] ?
elements [ id ] : ret ;
}
} ) ;
}
// shared
self . onChange = function ( ) {
// self.onChange(option, value)
// is called when an option changes
// (to be implemented by widget)
} ;
// public
that . defaults = function ( defaults ) {
/ *
that . defaults ( { foo : x } ) sets self . defaults
* /
self . defaults = defaults ;
return that ;
}
that . gain = function ( ) {
Ox . Focus . gain ( that . id ) ;
}
that . lose = function ( ) {
Ox . Focus . lose ( that . id ) ;
}
that . options = function ( ) {
/ *
that . options ( ) returns self . options
that . options ( "foo" ) returns self . options . foo
that . options ( "foo" , x ) sets self . options . foo ,
returns that
that . options ( { foo : x , bar : y } ) sets self . options . foo
and self . options . bar ,
returns that
* /
var length = arguments . length ,
args , ret ;
if ( length == 0 ) {
// options()
ret = self . options ;
} else if ( length == 1 && typeof arguments [ 0 ] == "string" ) {
// options(str)
ret = self . options [ arguments [ 0 ] ]
} else {
// options (str, val) or options({str: val, ...})
// translate (str, val) to ({str: val})
args = Ox . makeObject . apply ( that , arguments ) ;
// if options have not been set, extend defaults,
// otherwise, extend options
self . options = $ . extend (
self . options || self . defaults , args ) ;
$ . each ( args , function ( k , v ) {
self . onChange ( k , v ) ;
} ) ;
ret = that ;
}
return ret ;
}
that . publish = function ( ) {
arguments [ 0 ] = arguments [ 0 ] + "." + that . id ;
Ox . Event . publish . apply ( that , arguments ) ;
// or, maybe better:
$ ( ".OxWidget" ) . trigger . apply ( that , arguments ) ;
return that ;
}
that . remove = function ( ) {
that . $element . remove ( ) ;
delete elements [ that . ox ] ;
}
that . subscribe = function ( ) {
Ox . Event . subscribe . apply ( that , arguments ) ;
// or
that . $element . bind . apply ( that , arguments ) ;
return that ;
}
that . unsubscribe = function ( ) {
Ox . Event . unsubscribe . apply ( that , arguments ) ;
return that ;
}
// return
return that ;
}
} ( ) ;
Ox . _Element = function ( element ) {
var that = this ;
that . def = { } ;
that . opt = { } ;
that . ox = Ox . version ;
that . id = Ox . uid ( ) ;
//console.log("that.id", that.id)
that . $element = $ ( "<" + ( element || "div" ) + "/>" )
//.addClass("OxElement")
. data ( "ox" , that . id ) ;
oxui . elements [ that . id ] = that ;
// console.log("oxui.elements", oxui.elements)
//function setOption() {};
that . setOption = function ( ) { } ;
/ *
* /
that . destroy = function ( ) {
that . $element . remove ( ) ;
delete oxui . elements [ that . ox ] ;
}
/ *
* /
that . disable = function ( ) {
}
/ *
* /
that . enable = function ( ) {
}
/ *
* /
///*
that . defaults = function ( ) {
var length = arguments . length ,
ret ;
if ( length == 0 ) {
ret = that . def
} else if ( length == 1 && typeof arguments [ 0 ] == "string" ) {
ret = that . def [ arguments [ 0 ] ] ;
} else {
// translate ("key", "value") to {"key": "value"}
that . def = $ . extend (
that . def , Ox . makeObject . apply ( that , arguments )
) ;
ret = that ;
}
return ret ;
}
//*/
/ *
Ox . Element . options ( )
get options
Ox . Element . options ( "foo" )
get options . foo
Ox . Element . options ( "foo" , 0 )
set options . foo
Ox . Element . options ( { foo : 0 , bar : 1 } )
set options . foo and options . bar
* /
///*
that . options = function ( ) {
var length = arguments . length ,
args , ret ;
if ( length == 0 ) {
//console.log("getting all options", options);
ret = that . opt ;
} else if ( length == 1 && typeof arguments [ 0 ] == "string" ) {
//console.log("getting one option", options, arguments[0], options[arguments[0]]);
ret = that . opt [ arguments [ 0 ] ] ;
} else {
// translate ("key", "value") to {"key": "value"}
args = Ox . makeObject . apply ( that , arguments ) ;
// if options have been set then extend options,
// otherwise extend defaults
that . opt = $ . extend ( Ox . length ( that . opt ) ?
that . opt : that . def , args ) ;
// that.trigger("OxElement" + that.id + "SetOptions", args);
$ . each ( args , function ( k , v ) {
that . setOption ( k , v ) ;
//console.log("triggering", "OxElement" + that.id + "SetOption", {k: v})
//that.trigger("OxElement" + that.id + "SetOption", {k: v});
} )
ret = that ;
}
return ret ;
}
// should become self.publish
that . publish = function ( event , data ) {
Ox . Event . publish ( event + that . id , data ) ;
return that ;
}
that . subscribe = function ( event , callback ) {
Ox . Event . subscribe ( event , callback ) ;
return that ;
}
//that.setOptions = function() {};
//*/
// wrap jquery functions
// so we can do oxObj.jqFn()
$ . each ( oxui . jqueryFunctions , function ( i , v ) {
that [ v ] = function ( ) {
var args = arguments ,
length = args . length ,
$element , id , ret ;
$ . each ( args , function ( i , v ) {
// if an oxui object was passed
// then pass its $element instead
// so we can do jqObj.append(oxObj)
if ( v . ox ) {
args [ i ] = v . $element ;
}
} ) ;
if ( v == "html" && that . $content ) {
$element = that . $content ;
} else {
$element = that . $element ;
}
// why does this not work?
// ret = that.$element[v].apply(this, arguments);
// maybe because we pass this, and not that.$element[v] ... ?
// ret = that.$element[v].apply(that.$element[v], arguments);
// doesn't work either ...
if ( length == 0 ) {
ret = $element [ v ] ( ) ;
} else if ( length == 1 ) {
ret = $element [ v ] ( args [ 0 ] ) ;
} else if ( length == 2 ) {
ret = $element [ v ] ( args [ 0 ] , args [ 1 ] ) ;
} else if ( length == 3 ) {
ret = $element [ v ] ( args [ 0 ] , args [ 1 ] , args [ 2 ] ) ;
} else if ( length == 4 ) {
ret = $element [ v ] ( args [ 0 ] , args [ 1 ] , args [ 2 ] , args [ 3 ] ) ;
}
// if the $element of an oxui object was returned
// then return the oxui object instead
// so we can do oxObj.jqFn().oxFn()
//console.log("v", v, "arguments", arguments)
if ( ret . jquery ) {
//console.log("ret", ret, "ret.data('id')", ret.data("ox"))
}
return ret . jquery && oxui . elements [ id = ret . data ( "ox" ) ] ?
oxui . elements [ id ] : ret ;
}
} ) ;
return that ;
} ;
/ *
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Ox . theme ( )
get theme
Ox . theme ( "foo" )
set theme to "foo"
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
Ox . theme = function ( ) {
var length = arguments . length ,
classes = $body . attr ( "class" ) . split ( " " ) ,
arg , theme ;
$ . each ( classes , function ( i , v ) {
if ( Ox . startsWith ( v , "OxTheme" ) ) {
theme = v . replace ( "OxTheme" , "" ) . toLowerCase ( ) ;
if ( length == 1 ) {
$body . removeClass ( v ) ;
}
return false ;
}
} ) ;
if ( length == 1 ) {
arg = arguments [ 0 ]
$body . addClass ( "OxTheme" + Ox . toTitleCase ( arg ) ) ;
if ( theme ) {
$ ( "input[type=image]" ) . each ( function ( ) {
var $this = $ ( this ) ;
$this . attr ( {
src : $this . attr ( "src" ) . replace (
"/ox.ui." + theme + "/" , "/ox.ui." + arg + "/"
)
} ) ;
} ) ;
}
}
return theme ;
} ;
/ *
=== === === === === === === === === === === === === === === === === === === === === === === === === =
Bars
=== === === === === === === === === === === === === === === === === === === === === === === === === =
* /
Ox . Bar = function ( options , self ) {
var self = self || { } ,
that = new Ox . Element ( { } , self )
. defaults ( {
orientation : "horizontal" ,
size : 16
} )
. options ( options || { } ) ,
dimensions = oxui . getDimensions ( self . options . orientation ) ;
that . addClass ( "OxBar Ox" + Ox . toTitleCase ( self . options . orientation ) )
. css ( dimensions [ 0 ] , "100%" )
. css ( dimensions [ 1 ] , self . options . size + "px" ) ;
return that ;
} ;
/ *
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Ox . Tabbar
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
Ox . Tabbar = function ( options , self ) {
var self = self || { } ,
that = new Ox . Bar ( {
size : 20
} , self )
. defaults ( {
selected : 0 ,
values : [ ]
} )
. options ( options || { } )
. addClass ( "OxTabbar" ) ;
( function ( ) {
Ox . ButtonGroup ( {
selectable : true ,
selected : self . options . selected ,
size : "small" ,
style : "tab" ,
values : self . options . values
} ) . appendTo ( that ) ;
} ) ( ) ;
return that ;
} ;
Ox . Toolbar = function ( options , self ) {
var self = self || { } ,
that = new Ox . Bar ( {
size : oxui . getBarSize ( options . size )
} , self ) ;
return that ;
} ;
2010-01-27 12:30:00 +00:00
/ *
=== === === === === === === === === === === === === === === === === === === === === === === === === =
2010-01-31 08:03:22 +00:00
Ox . Dialog
2010-01-27 12:30:00 +00:00
=== === === === === === === === === === === === === === === === === === === === === === === === === =
* /
Ox . Dialog = function ( options , self ) {
var self = self || { } ,
options = $ . extend ( {
title : "" ,
buttons : [ ] ,
2010-01-31 08:03:22 +00:00
width : 384 ,
2010-01-27 12:30:00 +00:00
height : 128
} , options ) ,
that = new Ox . Element ( )
. addClass ( "OxDialog" )
. css ( {
left : ( ( $ ( document ) . width ( ) - options . width ) / 2 ) + "px" ,
2010-01-31 09:32:41 +00:00
top : ( ( $ ( document ) . height ( ) - options . height - 92 ) / 2 ) + "px" ,
2010-01-27 12:30:00 +00:00
width : options . width + "px" ,
2010-01-31 09:32:41 +00:00
height : ( options . height + 92 ) + "px"
2010-01-27 12:30:00 +00:00
} ) ;
2010-01-31 08:03:22 +00:00
that . $titlebar = new Ox . Bar ( {
size : "medium"
} )
2010-01-27 12:30:00 +00:00
. addClass ( "OxTitleBar" )
2010-01-31 08:03:22 +00:00
//.html(options.title)
2010-01-27 12:30:00 +00:00
. mousedown ( function ( e ) {
var offset = that . offset ( ) ,
//maxLeft = $(document).width() - that.width(),
//maxTop = $(document).height() - that.height(),
x = e . clientX ,
y = e . clientY ,
documentWidth = $ ( document ) . width ( ) ;
documentHeight = $ ( document ) . height ( ) ;
$ ( window ) . mousemove ( function ( e ) {
2010-01-31 08:03:22 +00:00
$ ( "*" ) . css ( {
WebkitUserSelect : "none"
} ) ;
var left = Ox . limit ( offset . left - x + e . clientX , 24 - options . width , documentWidth - 24 ) ,
top = Ox . limit ( offset . top - y + e . clientY , 24 , documentHeight - 24 ) ;
2010-01-27 12:30:00 +00:00
that . css ( {
left : left + "px" ,
top : top + "px"
} ) ;
} ) ;
$ ( window ) . one ( "mouseup" , function ( ) {
$ ( window ) . unbind ( "mousemove" ) ;
2010-01-31 08:03:22 +00:00
$ ( "*" ) . css ( {
WebkitUserSelect : "auto"
} ) ;
2010-01-27 12:30:00 +00:00
} ) ;
} )
. appendTo ( that ) ;
2010-01-31 08:03:22 +00:00
that . $title = new Ox . Element ( ) . addClass ( "OxTitle" ) . html ( options . title ) . appendTo ( that . $titlebar ) ;
2010-01-27 12:30:00 +00:00
that . $content = new Ox . Container ( )
. addClass ( "OxContent" )
. css ( {
height : options . height + "px"
} )
. appendTo ( that ) ;
that . $buttonsbar = new Ox . Element ( )
. addClass ( "OxButtonsBar" )
. appendTo ( that ) ;
2010-01-31 09:32:41 +00:00
that . $buttons = [ ] ;
$ . each ( options . buttons , function ( i , button ) {
that . $buttons [ i ] = new Ox . Button ( {
size : "medium" ,
value : button . value
} ) . click ( button . click ) . appendTo ( that . $buttonsbar ) ;
2010-01-27 12:30:00 +00:00
} ) ;
2010-01-31 09:32:41 +00:00
that . $buttons [ 0 ] . focus ( ) ;
2010-01-27 12:30:00 +00:00
that . $layer = $ ( ".OxLayer" ) ; // fixme: lazy loading of layer is fine, but save in var, dont look up
2010-01-31 08:03:22 +00:00
self . onChange = function ( key , value ) {
if ( key == "title" ) {
that . $title . html ( value ) ;
}
}
2010-01-27 12:30:00 +00:00
that . append = function ( $element ) {
that . $content . append ( $element ) ;
return that ;
}
2010-01-31 09:32:41 +00:00
that . close = function ( callback ) {
callback = callback || function ( ) { } ;
2010-01-27 12:30:00 +00:00
that . animate ( {
opacity : 0
} , 200 , function ( ) {
that . remove ( ) ;
that . $layer . remove ( ) ;
2010-01-31 09:32:41 +00:00
callback ( ) ;
2010-01-27 12:30:00 +00:00
} )
}
that . open = function ( ) {
if ( ! that . $layer . length ) {
that . $layer = new Ox . Element ( )
. addClass ( "OxLayer" )
. appendTo ( $ ( "body" ) ) ;
}
that . css ( {
opacity : 0
} ) . appendTo ( that . $layer ) . animate ( {
opacity : 1
} , 200 ) ;
return that ;
}
return that ;
}
2010-01-07 20:21:07 +00:00
/ *
=== === === === === === === === === === === === === === === === === === === === === === === === === =
Forms
=== === === === === === === === === === === === === === === === === === === === === === === === === =
* /
/ *
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Ox . Button
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
Ox . Button = function ( options , self ) {
var self = self || { } ,
that = new Ox . Element ( "input" , self )
. defaults ( {
buttonId : null ,
2010-02-03 12:12:21 +00:00
click : function ( ) { } ,
2010-01-07 20:21:07 +00:00
disabled : false ,
groupId : null ,
selectable : false ,
selected : false ,
size : "small" ,
style : "" , // can be symbol or tab
type : "text" ,
value : "" ,
values : [ ]
} )
. options ( $ . extend ( options , {
value : $ . isArray ( options . value ) ?
options . value [ 0 ] : options . value ,
values : $ . makeArray ( options . value )
} ) ) ;
that . attr ( {
disabled : self . options . disabled ? "disabled" : "" ,
type : self . options . type == "text" ? "button" : "image"
} )
. addClass ( "OxButton Ox" + Ox . toTitleCase ( self . options . size ) +
( self . options . style ? " Ox" + Ox . toTitleCase ( self . options . style ) : "" ) +
( self . options . disabled ? " OxDisabled" : "" ) +
( self . options . selected ? " OxSelected" : "" ) )
. mousedown ( mousedown )
. click ( click ) ;
//console.log(self.options.value, self.options.disabled)
/ *
that . bind ( "OxElement" + that . id + "SetOptions" , function ( e , data ) {
if ( typeof data . selected != "undefined" ) {
if ( data . selected != that . hasClass ( "OxSelected" ) ) {
that . toggleClass ( "OxSelected" ) ;
}
}
if ( typeof data . value != "undefined" ) {
if ( self . options . type == "image" ) {
that . attr ( {
src : oxui . path + "png/" + Ox . theme ( ) +
"/button" + Ox . toTitleCase ( options . value ) + ".png"
} ) ;
} else {
that . val ( self . options . value ) ;
}
}
} )
* /
function mousedown ( e ) {
if ( self . options . type == "image" && $ . browser . safari ) {
// keep image from being draggable
e . preventDefault ( ) ;
}
}
function click ( ) {
if ( self . options . selectable && ! ( self . options . groupId !== null && self . options . selected ) ) {
that . toggleSelected ( ) ;
}
if ( self . options . values . length == 2 ) {
console . log ( "2 values" )
that . options ( {
value : self . options . value == self . options . values [ 0 ] ?
self . options . values [ 1 ] : self . options . values [ 0 ]
} ) ;
}
2010-02-03 12:12:21 +00:00
self . options . click ( ) ;
2010-01-07 20:21:07 +00:00
}
self . onChange = function ( option , value ) {
//console.log("setOption", option, value)
if ( option == "selected" ) {
if ( value != that . hasClass ( "OxSelected" ) ) {
that . toggleClass ( "OxSelected" ) ;
}
}
if ( option == "value" ) {
if ( self . options . type == "image" ) {
that . attr ( {
src : oxui . path + "png/ox.ui." + Ox . theme ( ) +
"/button" + Ox . toTitleCase ( value ) + ".png"
} ) ;
} else {
that . val ( value ) ;
}
}
}
2010-01-31 08:03:22 +00:00
that . toggleDisabled = function ( ) {
that . options ( {
enabled : ! self . options . disabled
} ) ;
}
2010-01-07 20:21:07 +00:00
that . toggleSelected = function ( ) {
that . options ( {
selected : ! self . options . selected
} ) ;
that . trigger ( "OxButtonToggle" , self . options ) ;
}
that . options ( "value" , self . options . value ) ;
return that ;
} ;
/ *
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Ox . ButtonGroup
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
Ox . ButtonGroup = function ( options , self ) {
var self = self || { } ,
that = new Ox . Element ( { } , self )
. defaults ( {
groupId : Ox . uid ( ) ,
selectable : false ,
selected : - 1 ,
size : "small" ,
style : "" ,
type : "text" ,
values : [ ]
} )
. options ( options || { } )
. addClass ( "OxButtonGroup" ) ;
( function ( ) {
2010-02-03 12:12:21 +00:00
that . $buttons = [ ] ;
2010-01-07 20:21:07 +00:00
$ . each ( self . options . values , function ( i , v ) {
2010-02-03 12:12:21 +00:00
that . $buttons [ i ] = Ox . Button ( {
2010-01-07 20:21:07 +00:00
buttonId : i ,
groupId : self . options . groupId ,
selectable : self . options . selectable ,
selected : i == self . options . selected ,
size : self . options . size ,
style : self . options . style ,
type : self . options . type ,
value : v
} ) . appendTo ( that ) ;
} ) ;
that . $element . bind ( "OxButtonToggle" , function ( e , data ) {
console . log ( "Data" , data , self . options )
if ( data . groupId = self . options . groupId ) {
if ( data . selected ) {
if ( self . options . selected > - 1 ) {
2010-02-03 12:12:21 +00:00
that . $buttons [ self . options . selected ] . toggleSelected ( ) ;
2010-01-07 20:21:07 +00:00
}
self . options . selected = data . buttonId ;
}
}
} ) ;
} ) ( ) ;
return that ;
} ;
/ *
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Ox . Input
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
Ox . Input = function ( options , self ) {
var self = self || { } ,
that = new Ox . Element ( "input" , self )
. defaults ( {
placeholder : "" ,
size : "small" ,
type : "text"
} )
. options ( options || { } ) ;
2010-01-25 11:42:28 +00:00
that . attr ( {
2010-01-07 20:21:07 +00:00
type : self . options . type ,
placeholder : self . options . placeholder
} )
. addClass ( "OxInput Ox" +
Ox . toTitleCase ( self . options . size ) + " OxPlaceholder" )
//.change(change)
. focus ( focus )
. blur ( blur ) ;
/ * d o e s n ' t w o r k y e t
function change ( ) {
console . log ( "change" , that . val ( ) , that . hasClass ( "OxPlaceholder" ) )
if ( ( that . val ( ) !== "" ) != that . hasClass ( "OxPlaceholder" ) ) {
that . toggleClass ( "OxPlaceholder" ) ;
}
}
* /
function focus ( ) {
console . log ( "focus" , that . val ( ) , that . attr ( "class" ) )
if ( that . hasClass ( "OxPlaceholder" ) ) {
that . val ( "" ) . removeClass ( "OxPlaceholder" ) ;
}
}
function blur ( ) {
console . log ( "blur" , that . val ( ) , that . attr ( "class" ) )
if ( that . val ( ) === "" ) {
that . addClass ( "OxPlaceholder" ) . val ( that . attr ( "placeholder" ) ) ;
}
}
return that ;
} ;
/ *
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Ox . Range
options :
animate boolean if true , animate thumb
arrows boolean if true , show arrows
arrowImages array arrow symbols , like [ "minus" , "plus" ]
arrowStep number step when clicking arrows
max number maximum value
min number minimum value
orientation string "horizontal" or "vertical"
step number step between values
size number width or height , in px
thumbSize number minimum width or height of thumb , in px
thumbValue boolean if true , display value on thumb
trackImages string or array one or multiple track background image URLs
trackStep number 0 ( scroll here ) or step when clicking track
value number initial value
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
Ox . Range = function ( options , self ) {
/ *
init
* /
var self = self || { } ,
that = new Ox . Element ( { } , self )
. defaults ( {
animate : false ,
arrows : false ,
arrowImages : [ "previous" , "next" ] ,
arrowStep : 1 ,
max : 100 ,
min : 0 ,
orientation : "horizontal" ,
step : 1 ,
size : 128 ,
thumbSize : 16 ,
thumbValue : false ,
trackImages : [ ] ,
trackStep : 0 ,
value : 0
} )
. options ( $ . extend ( options , {
arrowStep : options . arrowStep ?
options . arrowStep : options . step ,
trackImages : $ . makeArray ( options . trackImages || [ ] )
} ) )
. addClass ( "OxRange" ) ;
// fixme: self. ... ?
var trackImages = self . options . trackImages . length ,
values = ( self . options . max - self . options . min + self . options . step ) /
self . options . step ;
/ *
construct
* /
that . $element
. css ( {
width : self . options . size + "px"
} ) ;
if ( self . options . arrows ) {
var $arrowDec = Ox . Button ( {
style : "symbol" ,
type : "image" ,
value : self . options . arrowImages [ 0 ]
} )
. addClass ( "OxArrow" )
. mousedown ( mousedownArrow )
. click ( clickArrowDec )
. appendTo ( that . $element ) ;
}
var $track = new Ox . Element ( )
. addClass ( "OxTrack" )
. mousedown ( clickTrack )
. appendTo ( that . $element ) ; // fixme: make that work
if ( trackImages ) {
var width = parseFloat ( screen . width / trackImages ) ,
$image = $ ( "<canvas/>" )
. attr ( {
width : width * trackImages ,
height : 14
} )
. addClass ( "OxImage" )
. appendTo ( $track . $element ) , // fixme: make that work
c = $image [ 0 ] . getContext ( '2d' ) ;
2010-01-25 15:10:44 +00:00
c . mozImageSmoothingEnabled = false ; // we may want to remove this later
2010-01-07 20:21:07 +00:00
$ . each ( self . options . trackImages , function ( i , v ) {
2010-01-25 15:10:44 +00:00
//console.log(v)
2010-01-07 20:21:07 +00:00
$ ( "<img/>" )
. attr ( {
src : v
} )
. load ( function ( ) {
c . drawImage ( this , i * width , 0 , width , 14 ) ;
} ) ;
} ) ;
}
var $thumb = Ox . Button ( { } )
. addClass ( "OxThumb" )
. appendTo ( $track ) ;
if ( self . options . arrows ) {
var $arrowInc = Ox . Button ( {
style : "symbol" ,
type : "image" ,
value : self . options . arrowImages [ 1 ]
} )
. addClass ( "OxArrow" )
. mousedown ( mousedownArrow )
. click ( clickArrowInc )
. appendTo ( that . $element ) ;
}
var rangeWidth , trackWidth , imageWidth , thumbWidth ;
setWidth ( self . options . size ) ;
/ *
private functions
* /
function clickArrowDec ( ) {
that . removeClass ( "OxActive" ) ;
setValue ( self . options . value - self . options . arrowStep , 200 )
}
function clickArrowInc ( ) {
that . removeClass ( "OxActive" ) ;
setValue ( self . options . value + self . options . arrowStep , 200 ) ;
}
function clickTrack ( e ) {
Ox . Focus . focus ( ) ;
var left = $track . offset ( ) . left ,
offset = $ ( e . target ) . hasClass ( "OxThumb" ) ?
e . clientX - $thumb . offset ( ) . left - thumbWidth / 2 - 2 : 0 ;
function val ( e ) {
return getVal ( e . clientX - left - offset ) ;
}
setValue ( val ( e ) , 200 ) ;
$window . mousemove ( function ( e ) {
setValue ( val ( e ) ) ;
} ) ;
$window . one ( "mouseup" , function ( ) {
$window . unbind ( "mousemove" ) ;
} ) ;
}
function getPx ( val ) {
var pxPerVal = ( trackWidth - thumbWidth - 2 ) /
( self . options . max - self . options . min ) ;
return Math . ceil ( ( val - self . options . min ) * pxPerVal + 1 ) ;
}
function getVal ( px ) {
var px = trackWidth / values >= 16 ? px : px - 8 ,
valPerPx = ( self . options . max - self . options . min ) /
( trackWidth - thumbWidth ) ;
return Ox . limit ( self . options . min +
Math . floor ( px * valPerPx / self . options . step ) * self . options . step ,
self . options . min , self . options . max ) ;
}
function mousedownArrow ( ) {
that . addClass ( "OxActive" ) ;
}
function setThumb ( animate ) {
var animate = typeof animate != "undefined" ? animate : 0 ;
$thumb . animate ( {
marginLeft : ( getPx ( self . options . value ) - 2 ) + "px" ,
width : thumbWidth + "px"
} , self . options . animate ? animate : 0 , function ( ) {
if ( self . options . thumbValue ) {
$thumb . options ( {
value : self . options . value
} ) ;
}
} ) ;
}
function setValue ( val , animate ) {
val = Ox . limit ( val , self . options . min , self . options . max ) ;
if ( val != self . options . value ) {
that . options ( {
value : val
} ) ;
setThumb ( animate ) ;
//console.log("triggering OxRange" + that.id + "Change")
that . publish ( "change" , { value : val } ) ;
}
}
function setWidth ( width ) {
trackWidth = width - self . options . arrows * 32 ;
thumbWidth = Math . max ( trackWidth / values - 2 , self . options . thumbSize - 2 ) ;
that . $element . css ( {
width : ( width - 2 ) + "px"
} ) ;
$track . css ( {
width : ( trackWidth - 2 ) + "px"
} ) ;
if ( trackImages ) {
$image . css ( {
width : ( trackWidth - 2 ) + "px"
} ) ;
}
$thumb . css ( {
width : ( thumbWidth - 2 ) + "px" ,
padding : 0
} ) ;
setThumb ( ) ;
}
/ *
shared functions
* /
self . onChange = function ( option , value ) {
}
return that ;
} ;
/ *
=== === === === === === === === === === === === === === === === === === === === === === === === === =
2010-02-02 16:03:11 +00:00
Menus
=== === === === === === === === === === === === === === === === === === === === === === === === === =
* /
Ox . MainMenu = function ( options , self ) {
}
Ox . Menu = function ( options , self ) {
var self = self || { } ,
that = new Ox . Element ( { } , self )
. defaults ( {
2010-02-04 08:02:23 +00:00
element : null ,
2010-02-02 16:03:11 +00:00
id : "" ,
items : [ ] ,
offset : {
left : 0 ,
top : 0
} ,
side : "bottom" ,
size : "medium"
} )
2010-02-03 12:12:21 +00:00
. options ( options )
. addClass (
"OxMenu Ox" + Ox . toTitleCase ( self . options . side ) +
" Ox" + Ox . toTitleCase ( self . options . size )
) ,
2010-02-02 16:03:11 +00:00
itemHeight = options . size == "small" ? 12 : ( options . size == "medium" ? 16 : 20 ) ,
selected = - 1 ,
scrollSpeed = 1 ,
$item ;
// construct
2010-02-04 08:02:23 +00:00
that . items = [ ] ;
that . submenus = { } ;
2010-02-02 16:03:11 +00:00
that . $scrollbars = [ ] ;
that . $top = $ ( "<div>" )
. addClass ( "OxTop" )
. appendTo ( that . $element ) ;
that . $scrollbars . up = constructScrollbar ( "up" )
. appendTo ( that . $element ) ;
that . $container = $ ( "<div>" )
. addClass ( "OxContainer" )
. appendTo ( that . $element ) ;
that . $content = $ ( "<table>" )
. addClass ( "OxContent" )
. appendTo ( that . $container ) ;
2010-02-03 12:12:21 +00:00
$ . each ( self . options . items , function ( i , item ) {
2010-02-02 16:03:11 +00:00
if ( item . id ) {
2010-02-04 08:02:23 +00:00
if ( ! $ . isEmptyObject ( item . submenu ) ) {
that . submenus [ item . id ] = new Ox . Menu ( item . submenu ) ;
}
$ . extend ( item , {
menu : that ,
submenu : that . submenus [ item . id ] || null
} ) ;
item = new Ox . MenuItem ( item )
2010-02-02 16:03:11 +00:00
. data ( "pos" , i )
. appendTo ( that . $content ) ;
2010-02-04 08:02:23 +00:00
that . items . push ( item ) ;
2010-02-02 16:03:11 +00:00
that . $content . append ( $item ) ;
} else {
that . $content . append ( constructSpace ( ) ) ;
that . $content . append ( constructLine ( ) ) ;
that . $content . append ( constructSpace ( ) ) ;
}
} ) ;
that . $scrollbars . down = constructScrollbar ( "down" )
. appendTo ( that . $element ) ;
that . $bottom = $ ( "<div>" )
. addClass ( "OxBottom" )
. appendTo ( that . $element ) ;
function constructLine ( ) {
2010-02-03 12:12:21 +00:00
return $ ( "<tr>" ) . append (
2010-02-04 08:02:23 +00:00
$ ( "<td>" , {
"class" : "OxLine" ,
colspan : 5
2010-02-03 12:12:21 +00:00
} )
) ;
2010-02-02 16:03:11 +00:00
}
function constructScrollbar ( direction ) {
2010-02-03 12:12:21 +00:00
var interval ;
return $ ( "<div/>" , {
2010-02-04 08:02:23 +00:00
addClass : "OxScrollbar Ox" + Ox . toTitleCase ( direction ) ,
2010-02-03 12:12:21 +00:00
html : oxui . symbols [ "triangle_" + direction ] ,
click : function ( ) { // fixme: do we need to listen to click event?
return false ;
} ,
mousedown : function ( ) {
scrollSpeed = 2 ;
return false ;
} ,
mouseenter : function ( ) {
var $otherScrollbar = that . $scrollbars [ direction == "up" ? "down" : "up" ] ;
$ ( this ) . addClass ( "OxSelected" ) ;
if ( $otherScrollbar . is ( ":hidden" ) ) {
$otherScrollbar . show ( ) ;
that . $container . height ( that . $container . height ( ) - itemHeight ) ;
if ( direction == "down" ) {
that . $content . css ( {
top : - itemHeight + "px"
} ) ;
}
}
scrollMenu ( direction == "up" ? - 1 : 1 ) ;
interval = setInterval ( function ( ) {
scrollMenu ( direction == "up" ? - 1 : 1 ) ;
} , 100 ) ;
} ,
mouseleave : function ( ) {
$ ( this ) . removeClass ( "OxSelected" ) ;
clearInterval ( interval ) ;
} ,
mouseup : function ( ) {
scrollSpeed = 1 ;
return false ;
}
} ) ;
2010-02-02 16:03:11 +00:00
}
function constructSpace ( ) {
2010-02-03 12:12:21 +00:00
return $ ( "<tr>" ) . append (
2010-02-04 08:02:23 +00:00
$ ( "<td>" , {
"class" : "OxSpace" ,
colspan : 5
2010-02-03 12:12:21 +00:00
} )
) ;
2010-02-02 16:03:11 +00:00
}
function getElement ( id ) {
return $ ( "#" + Ox . toCamelCase ( options . id + "/" + id ) ) ;
}
2010-02-03 12:12:21 +00:00
function scrollMenu ( speed ) {
var containerHeight = that . $container . height ( ) ,
contentHeight = that . $content . height ( ) ,
top = parseInt ( that . $content . css ( "top" ) ) || 0 ,
min = containerHeight - contentHeight + itemHeight ,
max = 0 ;
top += speed * scrollSpeed * - itemHeight ;
if ( top <= min ) {
top = min ;
that . $scrollbars . down . hide ( ) . trigger ( "mouseleave" ) ;
that . $container . css ( {
height : ( containerHeight + itemHeight ) + "px"
} ) ;
that . $items [ that . $items . length - 1 ] . trigger ( "mouseover" ) ;
} else if ( top >= max - itemHeight ) {
top = max ;
that . $scrollbars . up . hide ( ) . trigger ( "mouseleave" ) ;
that . $container . css ( {
height : ( containerHeight + itemHeight ) + "px"
} ) ;
that . $items [ 0 ] . trigger ( "mouseover" ) ;
}
that . $content . css ( {
top : top + "px"
} ) ;
2010-02-02 16:03:11 +00:00
}
function selectNextItem ( ) {
}
function selectPreviousItem ( ) {
}
that . hideMenu = function ( ) {
2010-02-04 08:02:23 +00:00
Ox . print ( "hideMenu" )
$ . each ( that . submenus , function ( i , submenu ) {
if ( ! submenu . is ( ":hidden" ) ) {
submenu . hideMenu ( ) ;
2010-02-03 12:12:21 +00:00
return false ;
}
} ) ;
// fixme: scroll menu back up!
that . hide ( ) ;
2010-02-02 16:03:11 +00:00
} ;
that . showMenu = function ( ) {
2010-02-03 12:12:21 +00:00
Ox . print ( "showMenu" )
2010-02-04 08:02:23 +00:00
that . parent ( ) . length || that . appendTo ( $body ) ;
var offset = self . options . element . offset ( ) ,
width = self . options . element . outerWidth ( ) ,
height = self . options . element . outerHeight ( ) ,
left = offset . left + self . options . offset . left + ( self . options . side == "bottom" ? 0 : width ) ,
top = offset . top + self . options . offset . top + ( self . options . side == "bottom" ? height : 0 ) ,
2010-02-03 12:12:21 +00:00
maxHeight = Math . floor ( ( $window . height ( ) - top - 12 ) / itemHeight ) * itemHeight ;
that . css ( {
left : left + "px" ,
top : top + "px"
} ) . show ( ) ;
if ( height > maxHeight ) {
that . $container . height ( maxHeight - itemHeight ) ;
that . $scrollbars . down . show ( ) ;
}
2010-02-02 16:03:11 +00:00
} ;
2010-02-03 12:12:21 +00:00
that . toggleMenu = function ( ) {
Ox . print ( "toggleMenu" )
that . is ( ":hidden" ) ? that . showMenu ( ) : that . hideMenu ( ) ;
2010-02-02 16:03:11 +00:00
} ;
return that ;
2010-02-03 12:12:21 +00:00
} ;
2010-02-02 16:03:11 +00:00
Ox . MenuItem = function ( options , self ) {
var self = self || { } ,
2010-02-03 12:12:21 +00:00
that = new Ox . Element ( "tr" , self )
2010-02-02 16:03:11 +00:00
. defaults ( {
bind : [ ] ,
2010-02-04 08:02:23 +00:00
checked : null ,
2010-02-02 16:03:11 +00:00
disabled : false ,
group : "" ,
icon : "" ,
id : "" ,
2010-02-03 12:12:21 +00:00
keyboard : "" ,
menu : null , // fixme: is passing the menu to 100s of menu items really memory-neutral?
submenu : null ,
title : [ ] ,
} )
. options ( $ . extend ( options , {
keyboard : parseKeyboard ( options . keyboard || self . defaults . keyboard ) ,
title : Ox . makeArray ( options . title || self . defaults . title )
} ) )
2010-02-04 08:02:23 +00:00
. addClass ( "OxItem" + ( self . options . disabled ? " OxDisabled" : "" ) )
2010-02-03 12:12:21 +00:00
. attr ( {
2010-02-04 08:02:23 +00:00
id : Ox . toCamelCase ( self . options . menu . id + "/" + self . options . id )
2010-02-03 12:12:21 +00:00
} )
. click ( click )
. data ( "group" , self . options . group )
. mouseenter ( mouseenter )
. mouseleave ( mouseleave ) ;
// construct
that . append (
that . $status = $ ( "<td>" , {
2010-02-04 08:02:23 +00:00
"class" : "OxCell OxStatus" ,
2010-02-03 12:12:21 +00:00
html : self . options . checked ? oxui . symbols . check : ""
} )
)
. append (
that . $icon = $ ( "<td>" , {
2010-02-04 08:02:23 +00:00
"class" : "OxCell OxIcon"
2010-02-02 16:03:11 +00:00
} )
2010-02-03 12:12:21 +00:00
. append ( self . options . icon ?
$ ( "<img>" , {
2010-02-04 08:02:23 +00:00
src : self . options . icon
2010-02-03 12:12:21 +00:00
} ) : null
)
)
. append (
that . $title = $ ( "<td>" , {
2010-02-04 08:02:23 +00:00
"class" : "OxCell OxTitle" ,
2010-02-03 12:12:21 +00:00
html : self . options . title [ 0 ]
} )
)
. append (
$ ( "<td>" , {
2010-02-04 08:02:23 +00:00
"class" : "OxCell OxModifiers" ,
2010-02-03 12:12:21 +00:00
html : $ . map ( self . options . keyboard . modifiers , function ( modifier ) {
return oxui . symbol [ modifier ] ;
} ) . join ( "" )
} )
)
. append (
$ ( "<td>" , {
2010-02-04 08:02:23 +00:00
"class" : "OxCell Ox" + ( self . options . submenu ? "Submenu" : "Key" ) ,
2010-02-03 12:12:21 +00:00
html : self . options . submenu ? oxui . symbols . triangle _right :
oxui . symbols [ self . options . keyboard . key ] || self . options . keyboard . key
} )
)
function click ( ) {
if ( ! that . hasClass ( "OxDisabled" ) && ! self . options . submenu ) {
2010-02-04 08:02:23 +00:00
self . options . menu . hideMenu ( ) ;
if ( self . options . checked !== null && ( ! self . options . group || ! self . options . checked ) ) {
2010-02-03 12:12:21 +00:00
that . options ( {
2010-02-04 08:02:23 +00:00
checked : ! self . options . checked
} ) ;
2010-02-03 12:12:21 +00:00
}
if ( self . options . title . length == 2 ) {
that . toggleTitle ( ) ;
}
2010-02-04 08:02:23 +00:00
$ ( "*" ) . trigger ( "OxClickMenu" , {
id : self . options . id ,
value : self . options . title // fixme: value or title?
} ) ;
2010-02-03 12:12:21 +00:00
return false ;
}
}
function mouseenter ( ) {
if ( ! that . is ( ".OxDisabled" ) && ! that . is ( ".OxSelected" ) ) {
$ . each ( self . options . menu . submenus , function ( id , submenu ) {
submenu . hideMenu ( ) ;
} ) ;
2010-02-04 08:02:23 +00:00
$ ( ".OxMenu .OxItem[id!=" + self . options . id + "]" ) . removeClass ( "selected" ) ;
2010-02-03 12:12:21 +00:00
self . options . submenu && self . options . submenu . showMenu ( ) ; // fixme: do we want to switch to this style?
that . addClass ( "OxSelected" ) ;
}
}
function mouseleave ( ) {
if ( ! that . hasClass ( "OxDisabled" ) && ! self . options . submenu ) {
that . removeClass ( "OxSelected" ) ;
}
}
function parseKeyboard ( str ) {
var modifiers = str . split ( ' ' ) ,
key = modifiers . pop ( ) ;
return {
modifiers : modifiers ,
key : key
}
}
self . onChange = function ( key , value ) {
2010-02-04 08:02:23 +00:00
Ox . print ( "MenuItem" , self . options . id , "onChange" , key , value ) ;
2010-02-03 12:12:21 +00:00
if ( key == "checked" ) {
2010-02-04 08:02:23 +00:00
if ( value && self . options . group ) {
$ . each ( self . options . menu . items , function ( i , item ) {
if (
item . options ( "id" ) != self . options . id &&
item . options ( "group" ) == self . options . group &&
item . options ( "checked" )
) {
item . options ( {
checked : false
} ) ;
return false ;
}
} ) ;
}
that . $status . html ( value ? oxui . symbols . check : "" )
2010-02-03 12:12:21 +00:00
} else if ( key == "disabled" ) {
that . toggleClass ( "disabled" ) ; // fixme: this will only work if onChange is only invoked on actual change
}
}
that . insertItemAfter = function ( item ) {
2010-02-02 16:03:11 +00:00
2010-02-03 12:12:21 +00:00
} ;
that . insertItemBefore = function ( item ) {
} ;
that . removeItem = function ( ) {
} ;
that . toggleChecked = function ( ) {
} ;
that . toggleDisabled = function ( ) {
} ;
that . toggleTitle = function ( ) {
that . options ( {
title : that . $title . html ( ) == self . options . title [ 0 ] ?
self . options . title [ 1 ] : self . options . title [ 0 ]
2010-02-02 16:03:11 +00:00
} )
2010-02-03 12:12:21 +00:00
} ;
2010-02-02 16:03:11 +00:00
return that ;
2010-02-03 12:12:21 +00:00
} ;
2010-02-02 16:03:11 +00:00
/ *
=== === === === === === === === === === === === === === === === === === === === === === === === === =
2010-01-07 20:21:07 +00:00
Panels
=== === === === === === === === === === === === === === === === === === === === === === === === === =
* /
/ *
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Ox . CollapsePanel
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
Ox . CollapsePanel = function ( options , self ) {
var self = self || { } ,
that = new Ox . Panel ( { } , self )
. defaults ( {
collapsed : false ,
size : 20 ,
title : ""
} )
. options ( options )
. addClass ( "OxCollapsePanel" ) ,
value = self . options . collapsed ?
[ "expand" , "collapsed" ] : [ "collapse" , "expand" ] ,
$titlebar = new Ox . Bar ( {
orientation : "horizontal" ,
size : self . options . size ,
} )
. dblclick ( dblclickTitlebar )
. appendTo ( that ) ,
$switch = new Ox . Button ( {
size : "small" ,
style : "symbol" ,
type : "image" ,
value : value ,
} )
. click ( toggleCollapsed )
. appendTo ( $titlebar ) ,
$title = new Ox . Element ( )
. addClass ( "OxTitle" )
. html ( self . options . title /*.toUpperCase()*/ )
. appendTo ( $titlebar ) ;
that . $content = new Ox . Element ( )
. addClass ( "OxContent" )
. appendTo ( that ) ;
// fixme: doesn't work, content still empty
// need to hide it if collapsed
if ( self . options . collapsed ) {
that . $content . css ( {
marginTop : - that . $content . height ( ) + "px"
} ) ;
}
function dblclickTitlebar ( e ) {
if ( ! $ ( e . target ) . hasClass ( "OxButton" ) ) {
toggleCollapsed ( ) ;
}
}
function toggleCollapsed ( ) {
that . options ( {
collapsed : ! self . options . collapsed
} ) ;
var top = self . options . collapsed ?
- that . $content . height ( ) : 0 ;
that . $content . animate ( {
marginTop : top + "px"
} , 200 ) ;
}
self . onChange = function ( option , value ) {
if ( option == "collapsed" ) {
$switch . options ( {
value : value ? "expand" : "collapse"
} ) ;
} else if ( option == "title" ) {
$title . html ( self . options . title ) ;
}
} ;
return that ;
} ;
/ *
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Ox . Panel
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
Ox . Panel = function ( options , self ) {
var self = self || { } ,
that = new Ox . Element ( { } , self )
. addClass ( "OxPanel" ) ;
return that ;
} ;
/ *
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Ox . SplitPanel
options :
orientation : "" "horizontal" or "vertical"
elements : [ {
element , Ox Element
size : 0 , size in px
resizable : false resizable or not
} ]
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
Ox . SplitPanel = function ( options , self ) {
var self = self || { } ,
that = new Ox . Element ( { } , self )
. defaults ( {
elements : [ ] ,
orientation : "horizontal"
} )
. options ( options || { } )
. addClass ( "OxSplitPanel" ) ,
length = self . options . elements . length ,
dimensions = oxui . getDimensions ( self . options . orientation ) ,
edges = oxui . getEdges ( self . options . orientation ) ;
$ . each ( self . options . elements , function ( i , v ) {
var element = v . element
. css ( {
position : "absolute" // fixme: this can go into a class
} )
. css ( edges [ 2 ] , 0 )
. css ( edges [ 3 ] , 0 ) ;
if ( v . size != undefined ) {
element . css ( dimensions [ 0 ] , v . size + "px" ) ;
}
if ( i == 0 ) {
element . css ( edges [ 0 ] , 0 ) ;
if ( v . size == undefined ) {
element . css (
edges [ 1 ] ,
( self . options . elements [ 1 ] . size + ( length == 3 ? self . options . elements [ 2 ] . size : 0 ) ) + "px"
) ;
}
} else if ( i == 1 ) {
if ( self . options . elements [ 0 ] . size != undefined ) {
element . css ( edges [ 0 ] , self . options . elements [ 0 ] . size + "px" ) ;
}
if ( self . options . elements [ 0 ] . size == undefined || v . size == undefined ) {
element . css (
edges [ 1 ] ,
( length == 3 ? self . options . elements [ 2 ] . size : 0 ) + "px"
) ;
}
} else {
element . css ( edges [ 1 ] , 0 ) ;
if ( v . size == undefined ) {
element . css (
edges [ 0 ] ,
( self . options . elements [ 0 ] . size + self . options . elements [ 1 ] . size ) + "px"
) ;
}
}
element . appendTo ( that ) ;
//that.append(element)
} ) ;
return that ;
} ;
2010-01-25 15:06:44 +00:00
} ) ( ) ;
2010-01-27 12:30:00 +00:00
/ *
=== === === === === === === === === === === === === === === === === === === === === === === === === =
Requests
=== === === === === === === === === === === === === === === === === === === === === === === === === =
* /
/ *
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Ox . Progressbar
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
/ *
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Ox . Spinner
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /