rsence-pre 2.1.8.1 → 2.2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. data/INSTALL.rdoc +3 -3
  2. data/README.rdoc +4 -4
  3. data/VERSION +1 -1
  4. data/conf/default_conf.yaml +4 -1
  5. data/js/comm/sessionwatcher/sessionwatcher.js +3 -2
  6. data/js/controls/textcontrol/textcontrol.js +45 -19
  7. data/js/core/elem/elem.js +6 -0
  8. data/js/datetime/timesheet/old_timesheet.js +292 -0
  9. data/js/datetime/timesheet/themes/default/old_timesheet.css +30 -0
  10. data/js/datetime/timesheet/themes/default/old_timesheet.html +2 -0
  11. data/js/datetime/timesheet/themes/default/timesheet.css +50 -22
  12. data/js/datetime/timesheet/themes/default/timesheet.html +4 -2
  13. data/js/datetime/timesheet/timesheet.js +448 -159
  14. data/js/datetime/timesheet_item/old_timesheet_item.js +308 -0
  15. data/js/datetime/timesheet_item/themes/default/old_timesheet_item.css +42 -0
  16. data/js/datetime/timesheet_item/themes/default/old_timesheet_item.html +8 -0
  17. data/js/datetime/timesheet_item/themes/default/timesheet_item.css +42 -11
  18. data/js/datetime/timesheet_item/themes/default/timesheet_item.html +4 -2
  19. data/js/datetime/timesheet_item/themes/default/timesheet_item_icons.png +0 -0
  20. data/js/datetime/timesheet_item/timesheet_item.js +156 -259
  21. data/js/datetime/timesheet_item_edit/old_timesheet_item_edit.js +274 -0
  22. data/js/datetime/timesheet_item_edit/timesheet_item_edit.js +0 -274
  23. data/js/foundation/control/valueaction/js.inc +0 -0
  24. data/js/foundation/control/valueaction/valueaction.js +72 -0
  25. data/js/foundation/locale_settings/js.inc +0 -0
  26. data/js/foundation/locale_settings/locale_settings.js +122 -0
  27. data/js/foundation/system/system.js +3 -2
  28. data/js/foundation/view/view.js +27 -0
  29. data/js/lists/checkboxlist/checkboxlist.js +9 -0
  30. data/js/lists/listitems/listitems.js +16 -0
  31. data/js/lists/radiobuttonlist/radiobuttonlist.js +17 -1
  32. data/js/menus/minimenu/minimenu.js +9 -5
  33. data/lib/conf/argv.rb +1 -0
  34. 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-ruby gem, you'll gain persistent sessions and this warning message will disappear:
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 specfically
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-ruby*:: SQLite[http://www.sqlite.org] is a light-weight SQL library. Recommended for development and small projects.
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 applitations. 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.
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 cretate 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.
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 featuers, just bugfixes) release.
93
- 2. rsence-pre : The active development snaphot released periodically.
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.8.1.pre
1
+ 2.2.0.0.pre
@@ -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
- if((new Date().getTime() - this.sesTimeoutValue.value) > this.timeoutSecs ){
42
- this.sesTimeoutValue.set( new Date().getTime() );
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.setValue(
76
- _this.validateText(
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
- _clipboardPasteTimer: null,
92
- clipboardPaste: function(){
93
- clearTimeout( this._clipboardPasteTimer ); this._clipboardPasteTimer = null;
94
- console.log('paste event, value now:',this.value);
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
+ }
@@ -0,0 +1,2 @@
1
+ <div class="timesheet_hours_col" id="label#{_ID}"></div>
2
+ <div class="timesheet_lines_col" id="state#{_ID}"></div>
@@ -1,30 +1,58 @@
1
- .timesheet_hours_col {
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
- top: 0px; left: 0px; width: 32px;
4
- font-family: Arial, sans-serif;
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: #666;
15
+ color: #000;
7
16
  vertical-align: middle;
8
- text-align: right;
17
+ text-align: left;
9
18
  }
10
- .timesheet_hours_row {
11
- position: absolute;
12
- left: 0px; width: 32px;
19
+
20
+ .timesheet_label {
21
+ left: 33px; top: 0px; right: 0px; height: 16px;
22
+ font-size: 15px;
13
23
  }
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;
24
+
25
+ .timesheet_timeline {
26
+ left: 0px; top: 0px; right: 0px; bottom: 0px;
20
27
  }
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;
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
- .timesheet_lines_row0 {
29
- background-color: #aaa;
56
+ .nohours .timesheet_items {
57
+ left: 0px;
30
58
  }
@@ -1,2 +1,4 @@
1
- <div class="timesheet_hours_col" id="label#{_ID}"></div>
2
- <div class="timesheet_lines_col" id="state#{_ID}"></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);}