rsence-pre 2.1.8.1 → 2.2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/INSTALL.rdoc +3 -3
- data/README.rdoc +4 -4
- data/VERSION +1 -1
- data/conf/default_conf.yaml +4 -1
- data/js/comm/sessionwatcher/sessionwatcher.js +3 -2
- data/js/controls/textcontrol/textcontrol.js +45 -19
- data/js/core/elem/elem.js +6 -0
- data/js/datetime/timesheet/old_timesheet.js +292 -0
- data/js/datetime/timesheet/themes/default/old_timesheet.css +30 -0
- data/js/datetime/timesheet/themes/default/old_timesheet.html +2 -0
- data/js/datetime/timesheet/themes/default/timesheet.css +50 -22
- data/js/datetime/timesheet/themes/default/timesheet.html +4 -2
- data/js/datetime/timesheet/timesheet.js +448 -159
- data/js/datetime/timesheet_item/old_timesheet_item.js +308 -0
- data/js/datetime/timesheet_item/themes/default/old_timesheet_item.css +42 -0
- data/js/datetime/timesheet_item/themes/default/old_timesheet_item.html +8 -0
- data/js/datetime/timesheet_item/themes/default/timesheet_item.css +42 -11
- data/js/datetime/timesheet_item/themes/default/timesheet_item.html +4 -2
- data/js/datetime/timesheet_item/themes/default/timesheet_item_icons.png +0 -0
- data/js/datetime/timesheet_item/timesheet_item.js +156 -259
- data/js/datetime/timesheet_item_edit/old_timesheet_item_edit.js +274 -0
- data/js/datetime/timesheet_item_edit/timesheet_item_edit.js +0 -274
- data/js/foundation/control/valueaction/js.inc +0 -0
- data/js/foundation/control/valueaction/valueaction.js +72 -0
- data/js/foundation/locale_settings/js.inc +0 -0
- data/js/foundation/locale_settings/locale_settings.js +122 -0
- data/js/foundation/system/system.js +3 -2
- data/js/foundation/view/view.js +27 -0
- data/js/lists/checkboxlist/checkboxlist.js +9 -0
- data/js/lists/listitems/listitems.js +16 -0
- data/js/lists/radiobuttonlist/radiobuttonlist.js +17 -1
- data/js/menus/minimenu/minimenu.js +9 -5
- data/lib/conf/argv.rb +1 -0
- metadata +21 -9
data/INSTALL.rdoc
CHANGED
@@ -84,7 +84,7 @@ Replace the +\my_projects+ path with the path to the directory where you want to
|
|
84
84
|
* Using just defaults, the following URL should work: http://127.0.0.1:8001
|
85
85
|
|
86
86
|
==== Windows limitations
|
87
|
-
If you install the sqlite dll and the sqlite3
|
87
|
+
If you install the sqlite dll and the sqlite3 gem, you'll gain persistent sessions and this warning message will disappear:
|
88
88
|
`Warning: Session database is not available. Can't use persistent sessions`
|
89
89
|
|
90
90
|
It's not a dependency in the default install, because it's not strictly required and makes the first installation much easier. Also, you can use any other database supported by Sequel instead of Sqlite.
|
@@ -132,12 +132,12 @@ This not only enables SessionStorage (persistent sessions between RSence restart
|
|
132
132
|
* *randgen*:: C-optimized random string generator developed for RSence specifically
|
133
133
|
* *jsmin_c*:: C-optimized Javascript whitespace removal library; Ruby wrapper developed for RSence specifically; based on the original JSMin[http://www.crockford.com/javascript/jsmin.html]
|
134
134
|
* *jscompress*:: C-optimized Javascript compression and obfuscation library developed for RSence specifically
|
135
|
-
* *html_min*:: C-optimized HTML whitespace removal library developed for RSence
|
135
|
+
* *html_min*:: C-optimized HTML whitespace removal library developed for RSence specifically
|
136
136
|
* *cssmin*:: CSS whitespace removal library
|
137
137
|
* *sequel*[http://sequel.rubyforge.org/]
|
138
138
|
* Generic SQL database ORM
|
139
139
|
* A Sequel driver for your preferred database is also needed:
|
140
|
-
* *sqlite3
|
140
|
+
* *sqlite3*:: SQLite[http://www.sqlite.org] is a light-weight SQL library. Recommended for development and small projects.
|
141
141
|
* Other database adapters compatible with Sequel are fine. Just configure RSence accordingly.
|
142
142
|
* *highline*:: Console-based menu prompt system by the init command.
|
143
143
|
* rmagick
|
data/README.rdoc
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
RSence is a RIA framework designed for responsive GUI applications on the web; it's implemented as a hybrid Ruby - Javascript system. The server is written in Ruby and C. Applications are installed as plugin bundles. The GUI framework is written in Javascript; it doesn't strictly require the server, but has extensive transport support with automatic data synchronization with the server. User interfaces are usually described in structured view trees represented by YAML data structures, which are automatically converted for rendering in the client.
|
7
7
|
|
8
|
-
Javascript knowledge is required only when creating custom client-driven functionality; basic understanding of the YAML GUITree structures is enough in most cases. Likewise, no prior Ruby knowledge is needed if you want to create stand-alone Javascript
|
8
|
+
Javascript knowledge is required only when creating custom client-driven functionality; basic understanding of the YAML GUITree structures is enough in most cases. Likewise, no prior Ruby knowledge is needed if you want to create stand-alone Javascript applications. Javascript component themes are easily created with just basic web designer skills. Data API's are easy to link no matter what language is used to create them. Skills in your organization are easily combined for various parts of larger applications.
|
9
9
|
|
10
10
|
RSence is not primarily targeted as an engine for plain old html web sites, there are plenty of other tools for that purpose and RSence is easily integrated with them in various ways.
|
11
11
|
|
@@ -17,7 +17,7 @@ Just run this command in the shell, if you have ruby installed. Otherwise, read
|
|
17
17
|
|
18
18
|
== Initializing a new project
|
19
19
|
|
20
|
-
The +init+ command will
|
20
|
+
The +init+ command will create a directory called `env_dir` in this example. It asks a few questions about the environment. Use a path and project name that matches your purposes.
|
21
21
|
rsence init /home/me/rsence_projects/env_dir
|
22
22
|
|
23
23
|
|
@@ -89,8 +89,8 @@ For more detailed installation and usage instructions, read the {file:INSTALL In
|
|
89
89
|
|
90
90
|
=== The bleeding edge (for developers)
|
91
91
|
RSence comes in two varieties:
|
92
|
-
1. rsence : The stable (no major new
|
93
|
-
2. rsence-pre : The active development
|
92
|
+
1. rsence : The stable (no major new features, just bug fixes) release.
|
93
|
+
2. rsence-pre : The active development snapshot released periodically.
|
94
94
|
|
95
95
|
Both varieties can be installed simultaneously and it's suggested to use
|
96
96
|
the stable "rsence" package for production installations and to use the
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.2.0.0.pre
|
data/conf/default_conf.yaml
CHANGED
@@ -198,7 +198,9 @@
|
|
198
198
|
|
199
199
|
# RSence.*
|
200
200
|
- rsence_ns
|
201
|
-
|
201
|
+
|
202
|
+
- locale_settings # HLocaleSettings
|
203
|
+
|
202
204
|
# RSence.Core
|
203
205
|
- class # HClass
|
204
206
|
- elem # ELEM
|
@@ -237,6 +239,7 @@
|
|
237
239
|
- eventmanager # EVENT
|
238
240
|
- controldefaults # HControlDefaults
|
239
241
|
- control # HControl
|
242
|
+
- valueaction # HValueAction
|
240
243
|
- dyncontrol # HDynControl
|
241
244
|
- centerview # HCenterView
|
242
245
|
- scrollview # HScrollView
|
@@ -38,8 +38,9 @@ COMM.SessionWatcher = HApplication.extend({
|
|
38
38
|
|
39
39
|
// Tells the server the client's current time
|
40
40
|
onIdle: function(){
|
41
|
-
|
42
|
-
|
41
|
+
var now = new Date().getTime();
|
42
|
+
if((now - this.sesTimeoutValue.value) > this.timeoutSecs ){
|
43
|
+
this.sesTimeoutValue.set( now );
|
43
44
|
}
|
44
45
|
}
|
45
46
|
});
|
@@ -28,9 +28,20 @@ HTextControl = HControl.extend({
|
|
28
28
|
|
29
29
|
controlDefaults: (HControlDefaults.extend({
|
30
30
|
refreshOnBlur: true,
|
31
|
-
refreshOnInput: true
|
31
|
+
refreshOnInput: true,
|
32
|
+
focusOnCreate: false
|
32
33
|
})),
|
33
34
|
|
35
|
+
drawSubviews: function(){
|
36
|
+
this.base();
|
37
|
+
if(this.options.focusOnCreate){
|
38
|
+
this.getInputElement().focus();
|
39
|
+
if( typeof this.value === 'string' ){
|
40
|
+
this.setSelectionRange( this.value.length, this.value.length );
|
41
|
+
}
|
42
|
+
}
|
43
|
+
},
|
44
|
+
|
34
45
|
/** = Description
|
35
46
|
* The contextMenu event for text input components is not prevented by default.
|
36
47
|
**/
|
@@ -72,33 +83,34 @@ HTextControl = HControl.extend({
|
|
72
83
|
_getChangeEventFn: function(){
|
73
84
|
var _this = this;
|
74
85
|
return function(e){
|
75
|
-
_this.
|
76
|
-
|
77
|
-
_this.getTextFieldValue()
|
78
|
-
)
|
79
|
-
);
|
80
|
-
if(e.type === 'paste'){
|
81
|
-
console.log('event: paste, e:', e);
|
82
|
-
if(_this._clipboardPasteTimer){
|
83
|
-
clearTimeout( this._clipboardPasteTimer );
|
84
|
-
}
|
85
|
-
this._clipboardPasteTimer = setTimeout( function(){_this.clipboardPaste();}, 200 );
|
86
|
+
if(_this._clipboardEventTimer){
|
87
|
+
clearTimeout( this._clipboardEventTimer );
|
86
88
|
}
|
89
|
+
_this._clipboardEventTimer = setTimeout( function(){_this.clipboardEvent();}, 200 );
|
87
90
|
return true;
|
88
91
|
};
|
89
92
|
},
|
90
93
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
94
|
+
_updateValueFromField: function(){
|
95
|
+
this.setValue(
|
96
|
+
this.validateText(
|
97
|
+
this.getTextFieldValue()
|
98
|
+
)
|
99
|
+
);
|
100
|
+
},
|
101
|
+
|
102
|
+
_clipboardEventTimer: null,
|
103
|
+
clipboardEvent: function(){
|
104
|
+
this._updateValueFromField();
|
105
|
+
clearTimeout( this._clipboardEventTimer );
|
106
|
+
this._clipboardEventTimer = null;
|
95
107
|
},
|
96
108
|
|
97
109
|
_changeEventFn: null,
|
98
110
|
_clearChangeEventFn: function(){
|
99
111
|
if( this._changeEventFn ){
|
100
|
-
Event.stopObserving( ELEM.get(this.markupElemIds.value), 'change', this._changeEventFn );
|
101
112
|
Event.stopObserving( ELEM.get(this.markupElemIds.value), 'paste', this._changeEventFn );
|
113
|
+
Event.stopObserving( ELEM.get(this.markupElemIds.value), 'cut', this._changeEventFn );
|
102
114
|
this._changeEventFn = null;
|
103
115
|
}
|
104
116
|
},
|
@@ -107,8 +119,8 @@ HTextControl = HControl.extend({
|
|
107
119
|
this._clearChangeEventFn();
|
108
120
|
}
|
109
121
|
this._changeEventFn = this._getChangeEventFn();
|
110
|
-
Event.observe( ELEM.get(this.markupElemIds.value), 'change', this._changeEventFn );
|
111
122
|
Event.observe( ELEM.get(this.markupElemIds.value), 'paste', this._changeEventFn );
|
123
|
+
Event.observe( ELEM.get(this.markupElemIds.value), 'cut', this._changeEventFn );
|
112
124
|
},
|
113
125
|
|
114
126
|
/** = Description
|
@@ -130,12 +142,18 @@ HTextControl = HControl.extend({
|
|
130
142
|
textBlur: function(){
|
131
143
|
this.hasTextFocus = false;
|
132
144
|
this._clearChangeEventFn();
|
145
|
+
this._updateValueFromField();
|
133
146
|
if(this.options.refreshOnBlur){
|
134
147
|
this.refreshValue();
|
135
148
|
}
|
136
149
|
return true;
|
137
150
|
},
|
138
|
-
|
151
|
+
|
152
|
+
onIdle: function(){
|
153
|
+
this.hasTextFocus && this._updateValueFromField();
|
154
|
+
this.base();
|
155
|
+
},
|
156
|
+
|
139
157
|
/** = Description
|
140
158
|
* refreshValue function
|
141
159
|
*
|
@@ -200,6 +218,14 @@ HTextControl = HControl.extend({
|
|
200
218
|
return '---'+Math.round((1+Math.random())*10000)+'---';
|
201
219
|
},
|
202
220
|
|
221
|
+
die: function(){
|
222
|
+
if( this.hasTextFocus ){
|
223
|
+
this.getInputElement().blur();
|
224
|
+
}
|
225
|
+
this._clearChangeEventFn();
|
226
|
+
this.base();
|
227
|
+
},
|
228
|
+
|
203
229
|
/** = Description
|
204
230
|
* Returns the selection (or text cursor position) of the input element
|
205
231
|
* as an +Array+ like +[ startOffset, endOffset ]+.
|
data/js/core/elem/elem.js
CHANGED
@@ -1016,6 +1016,9 @@ ELEM = {
|
|
1016
1016
|
if (_key === 'opacity') {
|
1017
1017
|
_this.setOpacity(_id, _value);
|
1018
1018
|
}
|
1019
|
+
else if ( !_elems[_id] ){
|
1020
|
+
console.log('ELEM#setStyle: Not a element! id:',_id,', key:',_key,', value:', _value);
|
1021
|
+
}
|
1019
1022
|
else {
|
1020
1023
|
_this._setElementStyle( _elems[_id], _key, _cached[_key] );
|
1021
1024
|
}
|
@@ -1203,6 +1206,9 @@ ELEM = {
|
|
1203
1206
|
if (_key === 'opacity') {
|
1204
1207
|
_this.setOpacity(_id, _cached[_key]);
|
1205
1208
|
}
|
1209
|
+
else if ( !_elem ){
|
1210
|
+
console.log('ELEM#_flushStyleCache: Not a element! id:',_id,', key:',_key,', value:', _value);
|
1211
|
+
}
|
1206
1212
|
else {
|
1207
1213
|
_this._setElementStyle( _elem, _key, _cached[_key] );
|
1208
1214
|
}
|
@@ -0,0 +1,292 @@
|
|
1
|
+
/* RSence
|
2
|
+
* Copyright 2009 Riassence Inc.
|
3
|
+
* http://riassence.com/
|
4
|
+
*
|
5
|
+
* You should have received a copy of the GNU General Public License along
|
6
|
+
* with this software package. If not, contact licensing@riassence.com
|
7
|
+
*/
|
8
|
+
|
9
|
+
/*** = Description
|
10
|
+
** HTimesheet is a simple timesheet control.
|
11
|
+
***/
|
12
|
+
var//RSence.DateTime
|
13
|
+
HTimeSheet = HControl.extend({
|
14
|
+
|
15
|
+
componentName: 'timesheet',
|
16
|
+
|
17
|
+
/* Default amount of pixels per hour. Override with options when necessary. */
|
18
|
+
pxPerHour: 24,
|
19
|
+
|
20
|
+
/* Default amount of pixels from left. Override with options when necessary. */
|
21
|
+
itemOffsetLeft: 36,
|
22
|
+
|
23
|
+
/* Default amount of pixels from right. Override with options when necessary. */
|
24
|
+
itemOffsetRight: 0,
|
25
|
+
|
26
|
+
defaultEvents: {
|
27
|
+
draggable: true
|
28
|
+
},
|
29
|
+
|
30
|
+
controlDefaults: HControlDefaults.extend({
|
31
|
+
pxPerHour: null,
|
32
|
+
itemOffsetLeft: null,
|
33
|
+
itemOffsetRight: null,
|
34
|
+
itemMinHeight: 24,
|
35
|
+
newItemLabel: 'New Item',
|
36
|
+
constructor: function(_ctrl){
|
37
|
+
if(this.pxPerHour !== null){
|
38
|
+
_ctrl.pxPerHour = this.pxPerHour;
|
39
|
+
}
|
40
|
+
if(this.itemOffsetLeft !== null){
|
41
|
+
_ctrl.itemOffsetLeft = this.itemOffsetLeft;
|
42
|
+
}
|
43
|
+
if(this.itemOffsetRight !== null){
|
44
|
+
_ctrl.itemOffsetRight = this.itemOffsetRight;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
}),
|
48
|
+
|
49
|
+
/** = Description
|
50
|
+
* Redraws the timesheet.
|
51
|
+
*
|
52
|
+
**/
|
53
|
+
refresh: function(){
|
54
|
+
if(this.drawn){
|
55
|
+
var _areaHeight = this.rect.height;
|
56
|
+
this.pxPerHour = (_areaHeight-(_areaHeight%48)) / 24;
|
57
|
+
if(this.options['hideLabel']){
|
58
|
+
this.setStyleOfPart( 'label', 'display', 'none' );
|
59
|
+
this.setStyleOfPart( 'state', 'left', '0px' );
|
60
|
+
this.itemOffsetLeft = 0;
|
61
|
+
}
|
62
|
+
else{
|
63
|
+
this.setStyleOfPart( 'label', 'height', (this.pxPerHour*24)+'px' );
|
64
|
+
}
|
65
|
+
this.setStyleOfPart( 'state', 'height', (this.pxPerHour*24)+'px' );
|
66
|
+
}
|
67
|
+
this.base();
|
68
|
+
},
|
69
|
+
|
70
|
+
/** = Description
|
71
|
+
* Refreshes the hour labels.
|
72
|
+
*
|
73
|
+
**/
|
74
|
+
refreshLabel: function(){
|
75
|
+
var hour = 1,
|
76
|
+
hours = [],
|
77
|
+
rowHeight = this.pxPerHour;
|
78
|
+
lineHeight = Math.round(this.pxPerHour/2);
|
79
|
+
for(; hour < 24; hour++){
|
80
|
+
hours.push('<div style="line-height:'+rowHeight+'px;height:'+rowHeight+'px;top:'+Math.round((hour*rowHeight)-lineHeight)+'px" class="timesheet_hours_row">'+hour+':00</div>');
|
81
|
+
}
|
82
|
+
this.markupElemIds && this.markupElemIds.label && ELEM.setHTML(this.markupElemIds.label,hours.join(''));
|
83
|
+
this.refreshState();
|
84
|
+
},
|
85
|
+
|
86
|
+
/** = Description
|
87
|
+
* Refreshes the lines which mark hours and half-hours.
|
88
|
+
*
|
89
|
+
**/
|
90
|
+
refreshState: function(){
|
91
|
+
var line = 0,
|
92
|
+
lines = [],
|
93
|
+
lineHeight = Math.round(this.pxPerHour/2);
|
94
|
+
for(; line < 48; line++){
|
95
|
+
lines.push('<div style="top:'+(line*lineHeight)+'px" class="timesheet_lines_row'+(line%2)+'"></div>');
|
96
|
+
}
|
97
|
+
this.markupElemIds && this.markupElemIds.label && ELEM.setHTML(this.markupElemIds.state,lines.join(''));
|
98
|
+
},
|
99
|
+
dragItem: false,
|
100
|
+
|
101
|
+
/** = Description
|
102
|
+
* Creates an item into timesheet with default label 'New Item'.
|
103
|
+
*
|
104
|
+
* = Parameters
|
105
|
+
* +origY+:: Y coordinate of the new item.
|
106
|
+
*
|
107
|
+
**/
|
108
|
+
createItem: function(origY){
|
109
|
+
var _lineHeight = Math.round(this.pxPerHour/2);
|
110
|
+
origY = Math.floor( origY / _lineHeight )*_lineHeight;
|
111
|
+
var maxY = _lineHeight*48,
|
112
|
+
lineHeight = Math.round(this.pxPerHour/2);
|
113
|
+
if(origY>maxY){
|
114
|
+
origY = maxY;
|
115
|
+
}
|
116
|
+
this.dragItem = this.createTimeSheetItem( { label: this.options.newItemLabel }, origY, lineHeight, 'create' );
|
117
|
+
},
|
118
|
+
|
119
|
+
/** = Description
|
120
|
+
* Dragging is used to mark items on the timesheet.
|
121
|
+
*
|
122
|
+
* = Parameters
|
123
|
+
* +x+:: x coordinate of the origin of drag
|
124
|
+
* +y+:: y coordinate of the origin of drag
|
125
|
+
*
|
126
|
+
**/
|
127
|
+
startDrag: function(x,y){
|
128
|
+
this._startDragTime = new Date().getTime();
|
129
|
+
this._startDragCoords = [x,y];
|
130
|
+
return true;
|
131
|
+
},
|
132
|
+
|
133
|
+
drag: function(x,y){
|
134
|
+
if(((new Date().getTime()) - this._startDragTime) < 200){
|
135
|
+
// only create when 200 ms has elapsed to enable clicking
|
136
|
+
return true;
|
137
|
+
}
|
138
|
+
if(this._startDragCoords[0]!==x && this._startDragCoords[1]!==y){
|
139
|
+
this.createItem(this._startDragCoords[1]-this.pageY());
|
140
|
+
EVENT.startDragging( this.dragItem );
|
141
|
+
return true;
|
142
|
+
}
|
143
|
+
},
|
144
|
+
|
145
|
+
click: function(x,y){
|
146
|
+
// deactivate all items
|
147
|
+
EVENT.changeActiveControl(this);
|
148
|
+
return true;
|
149
|
+
},
|
150
|
+
|
151
|
+
listItemViews: false,
|
152
|
+
|
153
|
+
/** = Description
|
154
|
+
* Sets the editor given as parameter as the editor of instance.
|
155
|
+
*
|
156
|
+
* = Parameters
|
157
|
+
* +_editor+::
|
158
|
+
*
|
159
|
+
**/
|
160
|
+
setEditor: function( _editor ){
|
161
|
+
this.editor = _editor;
|
162
|
+
},
|
163
|
+
|
164
|
+
/** = Description
|
165
|
+
* Returns HRect the size of given parameters and suitable for timesheet.
|
166
|
+
*
|
167
|
+
* = Parameters
|
168
|
+
* +_origY+:: Y coordinate.
|
169
|
+
* +_lineHeight+:: The height of item on time sheet.
|
170
|
+
*
|
171
|
+
**/
|
172
|
+
createItemRect: function(_origY, _lineHeight){
|
173
|
+
var _left = this.itemOffsetLeft+1,
|
174
|
+
_top = _origY+1,
|
175
|
+
_right = this.rect.width - this.itemOffsetRight - 1,
|
176
|
+
_bottom = _origY + _lineHeight - 2;
|
177
|
+
if( (_top - _bottom) < this.options.itemMinHeight ){
|
178
|
+
_bottom = _top + this.options.itemMinHeight;
|
179
|
+
}
|
180
|
+
return HRect.nu( _left, _top, _right, _bottom );
|
181
|
+
},
|
182
|
+
|
183
|
+
/** = Description
|
184
|
+
* Destructor; destroys the editor first and commences inherited die.
|
185
|
+
*
|
186
|
+
**/
|
187
|
+
die: function(){
|
188
|
+
this.editor.die();
|
189
|
+
this.base();
|
190
|
+
},
|
191
|
+
|
192
|
+
/** = Description
|
193
|
+
* Returns a new time sheet item control. By default returns an instance
|
194
|
+
* of HTimeSheetItem. Extend to use custom time sheet controls customized
|
195
|
+
* for application specific purposes.
|
196
|
+
*
|
197
|
+
* = Parameters
|
198
|
+
* *_value*:: A value object for the item.
|
199
|
+
* *_top*:: Top position, 0 by default.
|
200
|
+
* *_height*:: Height, same as half of +#pxPerHour+ by default.
|
201
|
+
* *_drogMode*:: Dragging mode. 'normal' or 'create'. Is 'normal' by default.
|
202
|
+
*
|
203
|
+
**/
|
204
|
+
createTimeSheetItem: function( _value, _top, _height, _dragMode ) {
|
205
|
+
if(_dragMode===undefined){
|
206
|
+
_dragMode = 'normal';
|
207
|
+
}
|
208
|
+
if(_top===undefined){
|
209
|
+
_top = 0;
|
210
|
+
}
|
211
|
+
if(_height===undefined){
|
212
|
+
_height = Math.round(this.pxPerHour/2);
|
213
|
+
}
|
214
|
+
var
|
215
|
+
_label = _value['label'],
|
216
|
+
_item = HTimeSheetItem.nu(
|
217
|
+
this.createItemRect( _top, _height ),
|
218
|
+
this, {
|
219
|
+
label: _label,
|
220
|
+
value: _value,
|
221
|
+
events: {
|
222
|
+
draggable: true
|
223
|
+
}
|
224
|
+
}
|
225
|
+
);
|
226
|
+
_item.dragMode = _dragMode;
|
227
|
+
return _item;
|
228
|
+
},
|
229
|
+
|
230
|
+
/** = Description
|
231
|
+
* Redraws and refreshes the values on timesheet.
|
232
|
+
*
|
233
|
+
**/
|
234
|
+
refreshValue: function(){
|
235
|
+
var
|
236
|
+
_data = this.value,
|
237
|
+
i;
|
238
|
+
if(this.listItemViews === false){
|
239
|
+
this.listItemViews = [];
|
240
|
+
}
|
241
|
+
else if(this.listItemViews.length > 0){
|
242
|
+
for( i=0; i<this.listItemViews.length; i++){
|
243
|
+
this.listItemViews[i].die();
|
244
|
+
}
|
245
|
+
this.listItemViews = [];
|
246
|
+
}
|
247
|
+
if(_data instanceof Array && _data.length > 0){
|
248
|
+
var
|
249
|
+
_value,
|
250
|
+
_item;
|
251
|
+
for( i=0; i<_data.length; i++){
|
252
|
+
_value = _data[i];
|
253
|
+
_item = this.createTimeSheetItem( _value );
|
254
|
+
this.listItemViews.push( _item );
|
255
|
+
}
|
256
|
+
}
|
257
|
+
var
|
258
|
+
_overlaps = [],
|
259
|
+
j;
|
260
|
+
for(i=0;i<this.listItemViews.length;i++){
|
261
|
+
for(j=0;j<this.listItemViews.length;j++){
|
262
|
+
if((i !== j) && (_overlaps.indexOf(i)===-1) && (_overlaps.indexOf(j)===-1)){
|
263
|
+
if(this.listItemViews[i].rect.intersects(this.listItemViews[j].rect)){
|
264
|
+
_overlaps.push(i);
|
265
|
+
}
|
266
|
+
}
|
267
|
+
}
|
268
|
+
}
|
269
|
+
var
|
270
|
+
_overlapCount = _overlaps.length+1,
|
271
|
+
_overlapLefts = {},
|
272
|
+
_itemWidth = ( this.rect.width - this.itemOffsetRight - this.itemOffsetLeft ),
|
273
|
+
_width = Math.floor( _itemWidth / _overlapCount),
|
274
|
+
_left = this.itemOffsetLeft;
|
275
|
+
for(j=0;j<_overlapCount;j++){
|
276
|
+
_overlapLefts[_overlaps[j]] = _left + (j*_width) + _width;
|
277
|
+
}
|
278
|
+
for(i=0;i<this.listItemViews.length;i++){
|
279
|
+
if(_overlaps.indexOf(i)===-1){
|
280
|
+
this.listItemViews[i].rect.setLeft(_left);
|
281
|
+
}
|
282
|
+
else {
|
283
|
+
this.listItemViews[i].rect.setLeft(_overlapLefts[i]);
|
284
|
+
}
|
285
|
+
this.listItemViews[i].rect.setWidth(_width);
|
286
|
+
}
|
287
|
+
for(i=0;i<this.listItemViews.length;i++){
|
288
|
+
this.listItemViews[i].drawRect();
|
289
|
+
}
|
290
|
+
}
|
291
|
+
});
|
292
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
.timesheet_hours_col {
|
2
|
+
position: absolute;
|
3
|
+
top: 0px; left: 0px; width: 32px;
|
4
|
+
font-family: Arial, sans-serif;
|
5
|
+
font-size: 11px;
|
6
|
+
color: #666;
|
7
|
+
vertical-align: middle;
|
8
|
+
text-align: right;
|
9
|
+
}
|
10
|
+
.timesheet_hours_row {
|
11
|
+
position: absolute;
|
12
|
+
left: 0px; width: 32px;
|
13
|
+
}
|
14
|
+
.timesheet_lines_col {
|
15
|
+
position: absolute;
|
16
|
+
top: 0px; left: 36px; right: 0px;
|
17
|
+
border-left: 1px solid #aaa;
|
18
|
+
border-bottom: 1px solid #aaa;
|
19
|
+
border-right: 1px solid #aaa;
|
20
|
+
}
|
21
|
+
.timesheet_lines_row0,
|
22
|
+
.timesheet_lines_row1 {
|
23
|
+
position: absolute;
|
24
|
+
left: 0px; right: 0px; height: 1px;
|
25
|
+
line-height: 1px; font-size: 0px;
|
26
|
+
background-color: #ccc;
|
27
|
+
}
|
28
|
+
.timesheet_lines_row0 {
|
29
|
+
background-color: #aaa;
|
30
|
+
}
|
@@ -1,30 +1,58 @@
|
|
1
|
-
.
|
1
|
+
.timesheet_label,
|
2
|
+
.timesheet_items,
|
3
|
+
.timesheet_timeline,
|
4
|
+
.timesheet_timeline_hour,
|
5
|
+
.timesheet_timeline_line,
|
6
|
+
.timesheet_timeline_notch {
|
2
7
|
position: absolute;
|
3
|
-
|
4
|
-
|
8
|
+
}
|
9
|
+
|
10
|
+
.timesheet_label,
|
11
|
+
.timesheet_items,
|
12
|
+
.timesheet_timeline {
|
13
|
+
font-family: Helvetica, Arial, sans-serif;
|
5
14
|
font-size: 11px;
|
6
|
-
color: #
|
15
|
+
color: #000;
|
7
16
|
vertical-align: middle;
|
8
|
-
text-align:
|
17
|
+
text-align: left;
|
9
18
|
}
|
10
|
-
|
11
|
-
|
12
|
-
left: 0px;
|
19
|
+
|
20
|
+
.timesheet_label {
|
21
|
+
left: 33px; top: 0px; right: 0px; height: 16px;
|
22
|
+
font-size: 15px;
|
13
23
|
}
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
border-left: 1px solid #aaa;
|
18
|
-
border-bottom: 1px solid #aaa;
|
19
|
-
border-right: 1px solid #aaa;
|
24
|
+
|
25
|
+
.timesheet_timeline {
|
26
|
+
left: 0px; top: 0px; right: 0px; bottom: 0px;
|
20
27
|
}
|
21
|
-
|
22
|
-
.
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
28
|
+
|
29
|
+
.timesheet_timeline_hour {
|
30
|
+
left: 0px; width: 26px; text-align: right; height: 14px;
|
31
|
+
}
|
32
|
+
|
33
|
+
.timesheet_timeline_line {
|
34
|
+
left: 31px; right: 3px; height: 1px; background-color: #bbb;
|
35
|
+
}
|
36
|
+
.timesheet_timeline_notch {
|
37
|
+
left: 31px; right: 3px; height: 1px; background-color: #ddd;
|
38
|
+
}
|
39
|
+
|
40
|
+
.timesheet_items {
|
41
|
+
left: 29px; top: 19px; right: 1px; bottom: 11px;
|
42
|
+
border: 1px outset #ccc;
|
43
|
+
border-radius: 3px;
|
44
|
+
}
|
45
|
+
|
46
|
+
.nohours .timesheet_timeline_notch,
|
47
|
+
.nohours .timesheet_timeline_line {
|
48
|
+
left: 2px;
|
49
|
+
}
|
50
|
+
.nohours .timesheet_timeline_hour {
|
51
|
+
display: none;
|
52
|
+
}
|
53
|
+
.nohours .timesheet_label {
|
54
|
+
left: 4px;
|
27
55
|
}
|
28
|
-
.
|
29
|
-
|
56
|
+
.nohours .timesheet_items {
|
57
|
+
left: 0px;
|
30
58
|
}
|
@@ -1,2 +1,4 @@
|
|
1
|
-
<div
|
2
|
-
<div
|
1
|
+
<div id="label#{_ID}" class="timesheet_label"></div>
|
2
|
+
<div id="timeline#{_ID}" class="timesheet_timeline"></div>
|
3
|
+
<div id="value#{_ID}" class="timesheet_items"></div>
|
4
|
+
${this.themeSettings(30, 20, 0, 10, -6);}
|