source: Dev/trunk/src/client/dojox/calendar/Keyboard.js @ 532

Last change on this file since 532 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

  • Property svn:executable set to *
File size: 9.7 KB
Line 
1define(["dojo/_base/array", "dojo/_base/lang", "dojo/_base/declare", "dojo/on", "dojo/_base/event", "dojo/keys"],
2        function(arr, lang, declare, on, event, keys){
3       
4        return declare("dojox.calendar.Keyboard", null, {
5
6                // summary:
7                //              This mixin is managing the keyboard interactions on a calendar view.
8               
9                // keyboardUpDownUnit: String
10                //              Unit used during editing of an event using the keyboard and the up or down keys were pressed. Valid values are "week", "day", "hours" "minute".
11                keyboardUpDownUnit: "minute",
12               
13                // keyboardUpDownSteps: Integer
14                //              Steps used during editing of an event using the keyboard and the up or down keys were pressed.         
15                keyboardUpDownSteps: 15,               
16               
17                // keyboardLeftRightUnit: String
18                //              Unit used during editing of an event using the keyboard and the left or right keys were pressed. Valid values are "week", "day", "hours" "minute".
19                keyboardLeftRightUnit: "day",
20               
21                // keyboardLeftRightSteps: Integer
22                //              Unit used during editing of an event using the keyboard and the left or right keys were pressed.               
23                keyboardLeftRightSteps: 1,
24
25                // allDayKeyboardUpDownUnit: Integer
26                //              Steps used during editing of an all day event using the keyboard and the up or down keys were pressed.
27                allDayKeyboardUpDownUnit: "day",
28               
29                // allDayKeyboardUpDownSteps: String
30                //              Unit used during editing of an all day event using the keyboard and the up or down keys were pressed. Valid values are "week", "day", "hours" "minute".         
31                allDayKeyboardUpDownSteps: 7,
32               
33                // allDayKeyboardLeftRightUnit: Integer
34                //              Steps used during editing of an all day event using the keyboard and the up or down keys were pressed.
35                allDayKeyboardLeftRightUnit: "day",
36               
37                // allDayKeyboardLeftRightSteps: String
38                //              Unit used during editing of an all day event using the keyboard and the left or right keys were pressed. Valid values are "week", "day", "hours" "minute".
39                allDayKeyboardLeftRightSteps: 1,
40
41                postCreate: function(){
42                        this.inherited(arguments);
43                        this._viewHandles.push(on(this.domNode, "keydown", lang.hitch(this, this._onKeyDown)));
44                },
45               
46                // resizeModfier: String
47                //              The modifier used to determine if the item is resized instead moved during the editing on an item.
48                resizeModifier: "ctrl",
49
50                // maxScrollAnimationDuration: Number
51                //              The duration in milliseconds to scroll the entire view.
52                //              The scroll speed is constant when scrolling to show an item renderer.
53                maxScrollAnimationDuration: 1000,
54               
55                ///////////////////////////////////////////////////////////////
56                //
57                // Focus management
58                //
59                //////////////////////////////////////////////////////////////
60               
61                // tabIndex: String
62                //              Order fields are traversed when user hits the tab key
63                tabIndex: "0",
64               
65                // focusedItem: Object
66                //              The data item that currently has the focus.
67                focusedItem: null,
68               
69                _isItemFocused: function(item){
70                        return this.focusedItem != null && this.focusedItem.id == item.id;
71                },
72
73                _setFocusedItemAttr: function(value){
74                        if(value != this.focusedItem){
75                                var old = this.focusedItem;
76                                this._set("focusedItem", value);
77                                this.updateRenderers([old, this.focusedItem], true);
78                                this.onFocusChange({
79                                        oldValue: old,
80                                        newValue: value
81                                });
82                        }
83                        if(value != null){
84                                if(this.owner != null && this.owner.get("focusedItem") != null){
85                                        this.owner.set("focusedItem", null);
86                                }
87                                if(this._secondarySheet != null && this._secondarySheet.set("focusedItem") != null){
88                                        this._secondarySheet.set("focusedItem", null);
89                                }
90                        }                       
91                },
92               
93                onFocusChange: function(e){
94                        // summary:
95                        //              Event dispatched when the focus has changed.
96                        // tags:
97                        //              callback
98
99                },
100
101                // showFocus: Boolean
102                //              Show or hide the focus graphic feedback on item renderers.
103                showFocus: false,               
104               
105                _focusNextItem: function(dir){                 
106                        // summary:
107                        //              Moves the focus to the next item in the specified direction.
108                        //              If there is no current child focused, the first (dir == 1) or last (dir == -1) is focused.
109                        // dir: Integer
110                        //              The direction of the next child to focus.
111                        //
112                        //              - 1: Move focus to the next item in the list.
113                        //              - -1: Move focus to the previous item in the list.
114                       
115                        if(!this.renderData || !this.renderData.items || this.renderData.items.length == 0){
116                                return null;
117                        }
118                       
119                        var index = -1;
120                        var list = this.renderData.items;
121                        var max = list.length - 1;
122                        var focusedItem = this.get("focusedItem");
123                       
124                        // find current index.
125                        if(focusedItem == null){
126                                index = dir > 0 ? 0 : max;
127                        }else{
128                                arr.some(list, lang.hitch(this, function(item, i){
129                                        var found = item.id == focusedItem.id;
130                                        if(found){
131                                                index = i;
132                                        }
133                                        return found;
134                                }));
135                                index = this._focusNextItemImpl(dir, index, max);
136                        }
137                       
138                        // find the first item with renderers.
139                        var reachedOnce = false;
140                        var old = -1;
141                       
142                        while(old != index && (!reachedOnce || index != 0)){
143                               
144                                if(!reachedOnce && index == 0){
145                                        reachedOnce = true;
146                                }
147                               
148                                var item = list[index];
149                               
150                                if(this.itemToRenderer[item.id] != null){
151                                        // found item
152                                        this.set("focusedItem", item);
153                                        return;
154                                }
155                                old = index;                           
156                                index = this._focusNextItemImpl(dir, index, max);
157                               
158                        }                                               
159                },
160               
161                _focusNextItemImpl: function(dir, index, max){
162                        // tags:
163                        //              private
164
165                        if(index == -1){ // not found should not occur
166                                index = dir > 0 ? 0 : max;
167                        }else{                         
168                                if(index == 0 && dir == -1 || index == max && dir == 1){
169                                        return index;
170                                }                               
171                                index = dir > 0 ? ++index : --index;                                   
172                        }                       
173                        return index;   
174                },
175               
176                ///////////////////////////////////////////////////////////
177                //
178                // Keyboard
179                //
180                //////////////////////////////////////////////////////////
181
182                _handlePrevNextKeyCode: function(e, dir){
183                        // tags:
184                        //              private
185
186                        if(!this.isLeftToRight()){
187                                dir = dir == 1 ? -1 : 1;
188                        }
189                        this.showFocus = true;
190                        this._focusNextItem(dir);
191                       
192                        var focusedItem = this.get("focusedItem");
193                       
194                        if(!e.ctrlKey && focusedItem){
195                                this.set("selectedItem", focusedItem);
196                        }
197
198                        if(focusedItem){
199                                this.ensureVisibility(focusedItem.startTime, focusedItem.endTime, "both", undefined, this.maxScrollAnimationDuration);
200                        }
201                },
202
203                _keyboardItemEditing: function(e, dir){
204                        // tags:
205                        //              private
206
207                        event.stop(e);
208
209                        var p = this._edProps;
210
211                        var unit, steps;
212
213                        if(p.editedItem.allDay || this.roundToDay || p.rendererKind == "label"){
214                                unit = dir == "up" || dir == "down" ? this.allDayKeyboardUpDownUnit : this.allDayKeyboardLeftRightUnit;
215                                steps = dir == "up" || dir == "down" ? this.allDayKeyboardUpDownSteps : this.allDayKeyboardLeftRightSteps;
216                        }else{
217                                unit = dir == "up" || dir == "down" ? this.keyboardUpDownUnit : this.keyboardLeftRightUnit;
218                                steps = dir == "up" || dir == "down" ? this.keyboardUpDownSteps : this.keyboardLeftRightSteps;
219                        }                       
220                                               
221                        if(dir == "up" || !this.isLeftToRight() && dir == "right" ||
222                                 this.isLeftToRight() && dir == "left"){
223                                steps = -steps;
224                        }
225                                               
226                        var editKind = e[this.resizeModifier+"Key"] ? "resizeEnd" : "move";
227                       
228                        var d = editKind == "resizeEnd" ? p.editedItem.endTime : p.editedItem.startTime;
229                       
230                        var newTime = this.renderData.dateModule.add(d, unit, steps);
231                       
232                        this._startItemEditingGesture([d], editKind, "keyboard", e);
233                        this._moveOrResizeItemGesture([newTime], "keyboard", e);
234                        this._endItemEditingGesture(editKind, "keyboard", e, false);
235                       
236                        if(editKind == "move"){
237                                if(this.renderData.dateModule.compare(newTime, d) == -1){
238                                        this.ensureVisibility(p.editedItem.startTime, p.editedItem.endTime, "start");
239                                }else{
240                                        this.ensureVisibility(p.editedItem.startTime, p.editedItem.endTime, "end");
241                                }                               
242                        }else{ // resize end only
243                                this.ensureVisibility(p.editedItem.startTime, p.editedItem.endTime, "end");     
244                        }                                               
245                },
246                                               
247                _onKeyDown: function(e){
248                        // tags:
249                        //              private
250
251                        var focusedItem = this.get("focusedItem");
252                       
253                        switch(e.keyCode){
254
255                                case keys.ESCAPE:
256
257                                        if(this._isEditing){
258                                               
259                                                if(this._editingGesture){
260                                                        this._endItemEditingGesture("keyboard", e, true);
261                                                }
262                                               
263                                                this._endItemEditing("keyboard", true);
264
265                                                this._edProps = null;
266                                        }
267                                        break;
268
269                                case keys.SPACE:
270
271                                        event.stop(e); // prevent browser shortcut
272
273                                        if(focusedItem != null){
274                                                this.setItemSelected(focusedItem, e.ctrlKey ? !this.isItemSelected(focusedItem) : true);
275                                        }
276                                        break;
277
278                                case keys.ENTER:
279
280                                        event.stop(e); // prevent browser shortcut
281
282                                        if(focusedItem != null){
283
284                                                if(this._isEditing){
285                                                        this._endItemEditing("keyboard", false);
286                                                }else{
287                                                       
288                                                        var renderers = this.itemToRenderer[focusedItem.id];
289                                                               
290                                                        if(renderers && renderers.length > 0 && this.isItemEditable(focusedItem, renderers[0].kind)){
291
292                                                                this._edProps = {
293                                                                        renderer: renderers[0],
294                                                                        rendererKind: renderers[0].kind,
295                                                                        tempEditedItem: focusedItem,
296                                                                        liveLayout: this.liveLayout
297                                                                };
298
299                                                                this.set("selectedItem", focusedItem);
300
301                                                                this._startItemEditing(focusedItem, "keyboard");
302                                                        }
303                                                }
304                                        }
305                                        break;
306
307                                case keys.LEFT_ARROW:
308                               
309                                        event.stop(e); // prevent browser shortcut
310                                       
311                                        if(this._isEditing){
312                                                this._keyboardItemEditing(e, "left");
313                                        }else{
314                                                this._handlePrevNextKeyCode(e, -1);
315                                        }                               
316                                        break;
317                                       
318                                case keys.RIGHT_ARROW:
319                               
320                                        event.stop(e); // prevent browser shortcut
321                                       
322                                        if(this._isEditing){
323                                                this._keyboardItemEditing(e, "right");
324                                        }else{
325                                                this._handlePrevNextKeyCode(e, 1);
326                                        }
327                                        break;
328                               
329                                case keys.UP_ARROW:
330                                        if(this._isEditing){
331                                                this._keyboardItemEditing(e, "up");
332                                        }else if(this.scrollable){
333                                                this.scrollView(-1);
334                                        }
335                                        break;
336                                       
337                                case keys.DOWN_ARROW:
338                                        if(this._isEditing){
339                                                this._keyboardItemEditing(e, "down");
340                                        }else if(this.scrollable){
341                                                this.scrollView(1);
342                                        }
343                                        break;
344                                       
345                        }
346                       
347                }
348        });
349});
Note: See TracBrowser for help on using the repository browser.