-
Notifications
You must be signed in to change notification settings - Fork 0
/
page-context.js
270 lines (247 loc) · 9.74 KB
/
page-context.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
var jsgui = require('jsgui2-lang');
var stringify = jsgui.stringify, each = jsgui.each, tof = jsgui.tof, is_defined = jsgui.is_defined;
var Control = jsgui.Control, Class = jsgui.Class;
var fp = jsgui.fp;
var group = jsgui.group;
var get_window_size = jsgui.get_window_size;
// this is the enhanced HTML module.
class Page_Context extends jsgui.Evented_Class{
'constructor'(spec) {
spec = spec || {};
if (spec.browser_info) {
this.browser_info = spec.browser_info;
};
if (spec.resource_pool) {
this.resource_pool = spec.resource_pool;
}
this.get_vector_methodology = function () {
if (this.browser_info.ie) {
return 'vml';
} else {
return 'svg';
}
};
// Copied from Server.Page_Context
var map_new_ids = {};
// and have the objects registered within the context too.
var map_objects = {};
var _get_new_typed_object_id = function(type_name) {
//console.log('map_new_ids', map_new_ids);
if (!is_defined(map_new_ids[type_name])) {
map_new_ids[type_name] = 0;
}
//if (!is_defined(map_new_ids[type_name]) {
// map_new_ids[type_name] = 0;
//}
var res = type_name + '_' + map_new_ids[type_name];
map_new_ids[type_name]++;
return res;
}
this.new_id = _get_new_typed_object_id;
this.set_max_ids = function(map_max_ids) {
each(map_max_ids, function(v, i) {
map_new_ids[i] = v + 1;
})
}
var map_Controls = this.map_Controls = {};
// they are constructors
var map_controls = this.map_controls = {};
map_Controls['control'] = Control;
}
'make'(abstract_object) {
if (abstract_object._abstract) {
//var res = new
// we need the constructor function.
var constructor = abstract_object.constructor;
//console.log('constructor ' + constructor);
//throw 'stop';
var aos = abstract_object._spec;
// could use 'delete?'
aos.abstract = null;
aos.context = this;
//console.log('abstract_object._spec ' + stringify(abstract_object._spec));
// Not sure it is creating the right constructor.
var res = new constructor(abstract_object._spec);
return res;
} else {
throw 'Object must be abstract, having ._abstract == true'
}
}
'update_Controls'() {
//console.log('update_Controls sig ' + sig);
var a = arguments; a.l = arguments.length; var sig = get_a_sig(a, 1);
if (sig == '[o]') {
// a map of keys and constructors values.
var o = a[0];
var map_Controls = this.map_Controls;
each(o, function(name, Constructor) {
name = name.toLowerCase();
//console.log('name ' + name);
map_Controls[name] = Constructor;
});
}
if (sig == '[s,f]') {
var name = a[0];
var Constructor = a[1];
name = name.toLowerCase();
//console.log('name ' + name);
this.map_Controls[name] = Constructor;
}
}
'register_control'(control) {
// Put it into the map of IDs
//console.log('register_control');
// Not sure how useful registration of all controls will be.
// Probably would not be a problem, just it will take memory and CPU cycles.
var id = control._id();
//console.log('id', id);
this.map_controls[id] = control;
}
'first_ctrl_matching_type'(type_name) {
// Want to iterate through the controls.
var res;
each(this.map_controls, function(ctrl, ctrl_id, fn_stop) {
//console.log('fn_stop', fn_stop);
//console.log('ctrl', ctrl);
//console.log('ctrl.__type_name', ctrl.__type_name);
if (ctrl.__type_name === type_name) {
//console.log('have match');
fn_stop();
res = ctrl;
}
});
return res;
}
'begin_drag_ctrl'(e_begin, ctrl) {
// Though the ctrl should probably go in the event object - maybe need to formalise an API.
// Different types of drag could be made modular to make builds smaller.
// For the moment need to add functionality then work on build size later.
this.raise('drag-ctrl-begin', e_end, ctrl);
}
'move_drag_ctrl'(e_move, ctrl) {
var window_size = get_window_size();
var from_left, from_top, from_right, from_bottom;
var clientX = e_move.clientX;
var clientY = e_move.clientY;
// see if it's at the top or bottom...
// would be nice to have different distances, so halfway to the margin anchors it in a way that it hides itself.
var margin = 64;
var is_left = clientX <= margin;
var is_top = clientY <= margin;
var is_right = clientX >= window_size[0] - margin;
var is_bottom = clientY >= window_size[1] - margin;
// need more generic event binding for objects.
// listen
// raise
// then for the combinations...
//console.log('is_top ' + is_top);
if (is_top) {
// raise the event...
// then some things will listen for it.
this.raise('drag-ctrl-top');
} else if (is_bottom) {
// raise the event...
// then some things will listen for it.
this.raise('drag-ctrl-bottom');
} else if (is_left) {
// raise the event...
// then some things will listen for it.
this.raise('drag-ctrl-left');
} else if (is_right) {
// raise the event...
// then some things will listen for it.
this.raise('drag-ctrl-right');
} else {
this.raise('drag-ctrl-no-zone');
}
}
'end_drag_ctrl'(e_end, ctrl) {
// raise the event...
this.raise('drag-ctrl-end', e_end, ctrl);
}
'drop_ctrl'(ctrl, zone) {
//console.log('page context drop control ctrl ' + ctrl);
//console.log('zone ' + zone);
if (this.full_window) {
// anchor the control in that zone.
this.anchor(ctrl, zone);
// Basically we need to anchor one control inside another.
// The anchor zone will be a part of the grid_9 (or other mechanism)
}
}
'anchor'(ctrl, zone) {
console.log('page context anchor ');
if (this.full_window) {
var fw = this.full_window;
// and then does the full window control have a grid_9?
var g9 = fw.get('grid_9');
//console.log('g9 ' + g9);
if (g9) {
g9.anchor_ctrl(ctrl, zone);
}
var fwtn = fw.__type_name;
//console.log('fwtn ' + fwtn);
}
}
// Ending a control drag.
// If we are to dock the control somewhere, we have some docking code that does this that can be called separately from the
// event.
// more than notify, this does some UI too.
'begin_drag_selection_scope': function(e_begin, selection_scope) {
//console.log('page context drag selection_scope ' + selection_scope);
var map_selected_controls = selection_scope.map_selected_controls;
//console.log('map_selected_controls ' + stringify(map_selected_controls));
// true keys...
var arr_selected = jsgui.true_vals(map_selected_controls);
//console.log('arr_selected.length ' + arr_selected.length);
// make shallow copies of these selected controls.
var shallow_copies_selected = jsgui.shallow_copy(arr_selected);
this.drag_selected = arr_selected;
var ctrl_abs = this.make(Control({
}));
ctrl_abs.add(shallow_copies_selected);
var screenX = e_begin.screenX;
//console.log('screenX ' + screenX);
var screenY = e_begin.screenY;
var clientX = e_begin.clientX;
var clientY = e_begin.clientY;
ctrl_abs.set('dom.attributes.style', 'position: absolute; left: ' + clientX + 'px; top:' + clientY + 'px; height: 200px; width: 320px; background-color: #EEEEEE');
var html = ctrl_abs.all_html_render();
var el_ctr = document.createElement('div');
el_ctr.innerHTML = html;
var el_abs = el_ctr.childNodes[0];
document.body.appendChild(el_abs);
//ctrl_abs.set('el', el_abs);
// within the context, we can make new controls and put them in the document.
// an absolutely positioned div.
this.ctrl_abs = ctrl_abs;
//throw 'stop';
}
'move_drag_selection_scope': function(e_move) {
console.log('page context move_drag_selection_scope');
var clientX = e_move.clientX;
var clientY = e_move.clientY;
// definitely would be useful to have the abstraction that covers individual style properties.
var style = 'position: absolute; left: ' + clientX + 'px; top:' + clientY + 'px; height: 200px; width: 320px; background-color: #EEEEEE'
//console.log('style ' + style);
var el = this.ctrl_abs.dom.el;
//console.log('el ' + el);
el.style.cssText = style;
}
'end_drag_selection_scope': function(e_end) {
if (this.ctrl_abs) {
this.ctrl_abs.remove();
this.ctrl_abs = null;
}
}
/*
'ensure_dock_placeholder': function(pos) {
//console.log('Page Context ensure_dock_placeholder ' + pos);
var fw = this.full_window;
if (fw) {
fw.ensure_dock_placeholder(pos);
}
}
*/
}
module.exports = Page_Context;