@usman404/crowjs 1.0.2
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.
- package/CONTRIBUTING.md +1 -0
- package/Core/Component.js +426 -0
- package/Core/GUIEvent/GUIEvent.js +23 -0
- package/Core/GUIEvent/KeyboardEvent.js +14 -0
- package/Core/GUIEvent/MouseEvent.js +22 -0
- package/Core/Root.js +558 -0
- package/Frames/DummyFrame.js +185 -0
- package/Frames/Frame.js +531 -0
- package/Frames/FrameComponent.js +54 -0
- package/Frames/GridFrame.js +574 -0
- package/Frames/ScrollFrame.js +764 -0
- package/LICENSE +21 -0
- package/README.md +130 -0
- package/UIComponents/Input.js +78 -0
- package/UIComponents/Label.js +234 -0
- package/UIComponents/TextField.js +551 -0
- package/UIComponents/UIComponent.js +97 -0
- package/crowjs-01-01.png +0 -0
- package/index.html +15 -0
- package/package.json +23 -0
- package/sketch.js +65 -0
|
@@ -0,0 +1,574 @@
|
|
|
1
|
+
import {Frame} from './Frame.js';
|
|
2
|
+
|
|
3
|
+
export class GridFrame extends Frame{
|
|
4
|
+
/**
|
|
5
|
+
* Creates a grid-based layout container
|
|
6
|
+
* @param {number} x - The x-coordinate
|
|
7
|
+
* @param {number} y - The y-coordinate
|
|
8
|
+
* @param {number} width - The width
|
|
9
|
+
* @param {number} height - The height
|
|
10
|
+
* @param {Object} options - Configuration options
|
|
11
|
+
* @param {string|null} options.id - Component ID
|
|
12
|
+
* @param {p5.Color} options.backgroundColor - Background color
|
|
13
|
+
* @param {p5.Color} options.borderColor - Border color
|
|
14
|
+
* @param {p5.Color} options.highlightedBorderColor - Highlighted border color
|
|
15
|
+
* @param {number} options.borderWidth - Border width
|
|
16
|
+
* @param {number} options.cornerRadius - Corner radius
|
|
17
|
+
* @param {number} options.padx - Horizontal padding
|
|
18
|
+
* @param {number} options.pady - Vertical padding
|
|
19
|
+
* @param {boolean} options.alwaysShowBanner - Always show banner
|
|
20
|
+
* @param {number} options.rows - Number of rows in grid
|
|
21
|
+
* @param {number} options.cols - Number of columns in grid
|
|
22
|
+
* @param {number} options.nearestBorderThreshold - Border detection threshold
|
|
23
|
+
* @param {number} options.bannerHeight - Banner height
|
|
24
|
+
* @param {Component|null} options.parent - Parent component
|
|
25
|
+
* @param {boolean} options.enableReposition - Allow dragging
|
|
26
|
+
* @param {boolean} options.enableOptimisedReposition - Optimized repositioning
|
|
27
|
+
* @param {boolean} options.enableResizing - Allow resizing
|
|
28
|
+
* @param {boolean} options.enableOptimisedResizing - Optimized resizing
|
|
29
|
+
* @param {boolean} options.enableShadow - Enable shadow
|
|
30
|
+
* @param {string} options.shadowColor - Shadow color
|
|
31
|
+
* @param {number} options.shadowIntensity - Shadow opacity
|
|
32
|
+
* @param {number} options.shadowSpread - Shadow spread
|
|
33
|
+
* @param {number} options.shadowDetail - Shadow layers
|
|
34
|
+
*/
|
|
35
|
+
constructor(x, y, width, height, {
|
|
36
|
+
id=null,
|
|
37
|
+
backgroundColor = color(255),
|
|
38
|
+
borderColor = color(0),
|
|
39
|
+
highlightedBorderColor = color(0),
|
|
40
|
+
borderWidth = 1,
|
|
41
|
+
cornerRadius = 0,
|
|
42
|
+
padx=0,
|
|
43
|
+
pady=0,
|
|
44
|
+
alwaysShowBanner = false,
|
|
45
|
+
rows=1,
|
|
46
|
+
cols=1,
|
|
47
|
+
nearestBorderThreshold=8,
|
|
48
|
+
bannerHeight=35,
|
|
49
|
+
parent=null,
|
|
50
|
+
enableReposition=false,
|
|
51
|
+
enableOptimisedReposition=false,
|
|
52
|
+
enableResizing=false,
|
|
53
|
+
enableOptimisedResizing=false,
|
|
54
|
+
enableShadow=false,
|
|
55
|
+
shadowColor= 'rgb(0,0,0)',
|
|
56
|
+
shadowIntensity = 0.3,
|
|
57
|
+
shadowSpread = 1,
|
|
58
|
+
shadowDetail = 10,
|
|
59
|
+
}
|
|
60
|
+
){
|
|
61
|
+
bannerHeight = bannerHeight%height;
|
|
62
|
+
super(x, y, width, height, id, backgroundColor, borderColor, highlightedBorderColor, borderWidth,
|
|
63
|
+
cornerRadius, padx, pady, alwaysShowBanner, bannerHeight, nearestBorderThreshold, parent, "Frame",
|
|
64
|
+
enableReposition, enableOptimisedReposition, enableResizing, enableOptimisedResizing, enableShadow, shadowColor, shadowIntensity, shadowSpread, shadowDetail);
|
|
65
|
+
|
|
66
|
+
//for storing child elements
|
|
67
|
+
this.rows=rows;
|
|
68
|
+
this.cols=cols;
|
|
69
|
+
this.rowWeights = [];
|
|
70
|
+
this.colWeights = [];
|
|
71
|
+
this.grid=null;
|
|
72
|
+
this.totalRowWeight = 0;
|
|
73
|
+
this.totalColWeight = 0;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Adds an element to the grid at specified position
|
|
78
|
+
* @param {Component} element - The component to add
|
|
79
|
+
* @param {number} row - Grid row index
|
|
80
|
+
* @param {number} col - Grid column index
|
|
81
|
+
* @param {Object} options - Placement options
|
|
82
|
+
* @param {number} options.rowSpan - Number of rows to span
|
|
83
|
+
* @param {number} options.colSpan - Number of columns to span
|
|
84
|
+
* @param {number} options.padL - Left padding
|
|
85
|
+
* @param {number} options.padR - Right padding
|
|
86
|
+
* @param {number} options.padT - Top padding
|
|
87
|
+
* @param {number} options.padB - Bottom padding
|
|
88
|
+
*/
|
|
89
|
+
add(element, row, col, {
|
|
90
|
+
rowSpan=1,
|
|
91
|
+
colSpan=1,
|
|
92
|
+
padL=0,
|
|
93
|
+
padR=0,
|
|
94
|
+
padT=0,
|
|
95
|
+
padB=0
|
|
96
|
+
}={})
|
|
97
|
+
{
|
|
98
|
+
//check if grid is configured or not
|
|
99
|
+
if(this.grid===null){
|
|
100
|
+
console.log("element can't be added: gird not configured,");
|
|
101
|
+
console.log("call .gridConfig(rows, cols) to configure grid before adding any elements!");
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if(element===null){
|
|
106
|
+
console.log("element to add can't be null");
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if(this.findElement(element)){
|
|
111
|
+
console.log(`the component (id: ${element.id}) is already added to the Gridframe (${this.id})`);
|
|
112
|
+
console.log("component: ", element, "\nGridFrame: ", this);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if(row<0 || row>=this.rows || col<0 || col>=this.cols){
|
|
117
|
+
console.log("index out of range; can't add the element at (",row,",",col,")");
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if(this.grid[row][col]!=null){
|
|
122
|
+
console.log("Grid cell (",row,",",col,") already taken");
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if(this.getElementById(element.id)){
|
|
127
|
+
console.log(`component with duplicate id (${element.id}) found in ${this.constructor.name}; component (${element.constructor.name}) can't be added!`);
|
|
128
|
+
console.log(this);
|
|
129
|
+
console.log("");
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
element.turnResizingAndRepositionOff();
|
|
134
|
+
element.parent=this;
|
|
135
|
+
this.children.push(element);
|
|
136
|
+
this.grid[row][col] = [element, rowSpan, colSpan, padL, padR, padT, padB];
|
|
137
|
+
this.adjustToGrid(row, col, rowSpan, colSpan);
|
|
138
|
+
|
|
139
|
+
// this.printGrid();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Finds the grid position of an element
|
|
144
|
+
* @param {Component} element - The element to find
|
|
145
|
+
* @returns {number[]|null} [row, col] or null if not found
|
|
146
|
+
*/
|
|
147
|
+
getElementPos(element){
|
|
148
|
+
for(let i=0; i<this.rows; i++){
|
|
149
|
+
for(let j=0; j<this.cols; j++){
|
|
150
|
+
if(this.grid[i][j][0]===element)
|
|
151
|
+
return [i, j];
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Removes an element from the grid
|
|
160
|
+
* @param {Component} element - The element to remove
|
|
161
|
+
*/
|
|
162
|
+
remove(element){
|
|
163
|
+
let index = this.findIndexOfElement(element);
|
|
164
|
+
if(index==-1){
|
|
165
|
+
console.log(`element (id: ${element.id}) can't be removed from ScrollFrame (id: ${this.id})
|
|
166
|
+
because it was not found in immediate children!`);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
element.parent = null;
|
|
171
|
+
let res = this.getElementPos(element);
|
|
172
|
+
// console.log(res);
|
|
173
|
+
let x = res[0];
|
|
174
|
+
let y = res[1];
|
|
175
|
+
let rowSpan = this.grid[x][y][1];
|
|
176
|
+
let colSpan = this.grid[x][y][2];
|
|
177
|
+
//reclaiming the space taken up by the
|
|
178
|
+
//element in the grid
|
|
179
|
+
if(res !== null){
|
|
180
|
+
for(let i=x; i < x+rowSpan; i++){
|
|
181
|
+
for(let j=y; j< y+colSpan; j++){
|
|
182
|
+
this.grid[i][j] = null;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
this.removeChild(element);
|
|
188
|
+
this.redraw();
|
|
189
|
+
console.log(`element (id: ${element.id}) successfully removed from ${this.constructor.name} (id: ${this.id})!`);
|
|
190
|
+
// this.printGrid();
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Configures row weight for proportional sizing
|
|
195
|
+
* @param {number} rowNum - Row index to configure
|
|
196
|
+
* @param {number} weight - Weight value for proportional sizing
|
|
197
|
+
*/
|
|
198
|
+
rowConfig(rowNum, weight){
|
|
199
|
+
if(rowNum<0 || rowNum>=this.rows){
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if(this.rowWeights[rowNum]!=null){
|
|
203
|
+
this.totalRowWeight-=this.rowWeights[rowNum];
|
|
204
|
+
}
|
|
205
|
+
this.rowWeights[rowNum] = weight;
|
|
206
|
+
this.totalRowWeight+=weight;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Configures column weight for proportional sizing
|
|
211
|
+
* @param {number} colNum - Column index to configure
|
|
212
|
+
* @param {number} weight - Weight value for proportional sizing
|
|
213
|
+
*/
|
|
214
|
+
colConfig(colNum, weight){
|
|
215
|
+
if(colNum<0 || colNum>=this.cols){
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
if(this.colWeights[colNum]!=null){
|
|
219
|
+
this.totalColWeight-=this.colWeights[colNum];
|
|
220
|
+
}
|
|
221
|
+
this.colWeights[colNum] = weight;
|
|
222
|
+
this.totalColWeight+=weight;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Initializes the grid structure with specified rows and columns
|
|
227
|
+
* @param {number} rows - Number of rows
|
|
228
|
+
* @param {number} cols - Number of columns
|
|
229
|
+
*/
|
|
230
|
+
gridConfig(rows, cols){
|
|
231
|
+
this.rows = rows;
|
|
232
|
+
this.cols = cols;
|
|
233
|
+
|
|
234
|
+
for(let i=0; i<this.rows; i++){
|
|
235
|
+
this.rowConfig(i, 1);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
for(let i=0; i<this.cols; i++){
|
|
239
|
+
this.colConfig(i, 1);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
this.grid = new Array(this.rows);
|
|
243
|
+
for(let i=0; i<this.rows; i++){
|
|
244
|
+
this.grid[i] = new Array(this.cols);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
for(let i=0; i<this.rows; i++){
|
|
248
|
+
for(let j=0; j<this.cols; j++){
|
|
249
|
+
this.grid[i][j]=null;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Adjusts child component widths based on grid weights
|
|
256
|
+
* @param {number} x - Starting x position
|
|
257
|
+
* @param {number} w - Available width
|
|
258
|
+
*/
|
|
259
|
+
adjustWidth(x, w){
|
|
260
|
+
//[element, rowSpan, colSpan, padL, padR, padT, padB];
|
|
261
|
+
for(let i=0; i<this.cols; i++){
|
|
262
|
+
for(let j=0; j<this.rows; j++){
|
|
263
|
+
if(this.grid && this.grid[j][i]!=null && this.grid[j][i]!="taken"){
|
|
264
|
+
let curr = this.grid[j][i];
|
|
265
|
+
|
|
266
|
+
curr[0].x = x + curr[3];
|
|
267
|
+
curr[0].width = 0;
|
|
268
|
+
|
|
269
|
+
for(let k=0; k<curr[2]; k++){
|
|
270
|
+
curr[0].width += (this.colWeights[i+k]/this.totalColWeight) * w;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
curr[0].width -= curr[3] + curr[4];
|
|
274
|
+
|
|
275
|
+
if(curr[0].type=="Frame"){
|
|
276
|
+
curr[0].adjustWidth(curr[0].x + curr[0].padx, curr[0].width - 2*curr[0].padx);
|
|
277
|
+
} else {
|
|
278
|
+
curr[0].updateWidth();
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
x += (this.colWeights[i]/this.totalColWeight) * w;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Adjusts child component heights based on grid weights
|
|
290
|
+
* @param {number} y - Starting y position
|
|
291
|
+
* @param {number} h - Available height
|
|
292
|
+
*/
|
|
293
|
+
adjustHeight(y, h){
|
|
294
|
+
//[element, rowSpan, colSpan, padL, padR, padT, padB];
|
|
295
|
+
for(let i=0; i<this.rows; i++){
|
|
296
|
+
for(let j=0; j<this.cols; j++){
|
|
297
|
+
if(this.grid && this.grid[i][j]!=null && this.grid[i][j]!="taken"){
|
|
298
|
+
let curr = this.grid[i][j];
|
|
299
|
+
|
|
300
|
+
curr[0].y = y + curr[5];
|
|
301
|
+
curr[0].height = 0;
|
|
302
|
+
|
|
303
|
+
for(let k=0; k<curr[1]; k++){
|
|
304
|
+
curr[0].height += (this.rowWeights[i+k]/this.totalRowWeight) * h;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
curr[0].height -= curr[5] + curr[6];
|
|
308
|
+
|
|
309
|
+
//console.log("curr[0].type:"+curr[0].type);
|
|
310
|
+
|
|
311
|
+
if(curr[0].type=="Frame"){
|
|
312
|
+
curr[0].adjustHeight(curr[0].y + curr[0].pady, curr[0].height - 2*curr[0].pady);
|
|
313
|
+
} else {
|
|
314
|
+
curr[0].updateHeight();
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
y += (this.rowWeights[i]/this.totalRowWeight) * h;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
//only called when a new element is added
|
|
324
|
+
//to make the element fit into the grid cell
|
|
325
|
+
/**
|
|
326
|
+
* Positions a new element within the grid cell
|
|
327
|
+
* @param {number} row - Row index
|
|
328
|
+
* @param {number} col - Column index
|
|
329
|
+
* @param {number} rowSpan - Row span
|
|
330
|
+
* @param {number} colSpan - Column span
|
|
331
|
+
*/
|
|
332
|
+
adjustToGrid(row, col, rowSpan, colSpan){
|
|
333
|
+
let x = this.x + this.padx;
|
|
334
|
+
let y = this.y + this.pady;
|
|
335
|
+
if(this.alwaysShowBanner){
|
|
336
|
+
y += this.bannerHeight;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
let w = this.width - 2*this.padx;
|
|
340
|
+
let h = this.height - 2*this.pady;
|
|
341
|
+
if(this.alwaysShowBanner){
|
|
342
|
+
h -= this.bannerHeight;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
for(let i=0; i<col; i++){
|
|
346
|
+
x += (this.colWeights[i]/this.totalColWeight) * w;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
for(let i=0; i<row; i++){
|
|
350
|
+
y += (this.rowWeights[i]/this.totalRowWeight) * h;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
this.grid[row][col][0].x = x + this.grid[row][col][3];
|
|
354
|
+
this.grid[row][col][0].y = y + this.grid[row][col][5];
|
|
355
|
+
|
|
356
|
+
this.expandElement(row, col, rowSpan, colSpan);
|
|
357
|
+
|
|
358
|
+
//this.storeProportions(row, col);
|
|
359
|
+
|
|
360
|
+
if(this.grid[row][col][0].constructor.name=="GridFrame"){
|
|
361
|
+
this.grid[row][col][0].adjustWidth(this.grid[row][col][0].x + this.grid[row][col][0].padx, this.grid[row][col][0].width - 2*this.grid[row][col][0].padx);
|
|
362
|
+
this.grid[row][col][0].adjustHeight(this.grid[row][col][0].y + this.grid[row][col][0].pady, this.grid[row][col][0].height - 2*this.grid[row][col][0].pady);
|
|
363
|
+
} else if(this.grid[row][col][0].constructor.name=="ScrollFrame"){
|
|
364
|
+
this.grid[row][col][0].redraw();
|
|
365
|
+
} else {
|
|
366
|
+
this.grid[row][col][0].updateWidth();
|
|
367
|
+
if(this.grid[row][col][0].constructor.name!="Label"){
|
|
368
|
+
this.grid[row][col][0].updateHeight();
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
//expand the element to as much grid cells as possible
|
|
374
|
+
//while keeping the desired row and col spans in consideration
|
|
375
|
+
/**
|
|
376
|
+
* Expands element to span multiple grid cells
|
|
377
|
+
* @param {number} row - Starting row
|
|
378
|
+
* @param {number} col - Starting column
|
|
379
|
+
* @param {number} rowSpan - Desired row span
|
|
380
|
+
* @param {number} colSpan - Desired column span
|
|
381
|
+
*/
|
|
382
|
+
expandElement(row, col, rowSpan, colSpan){
|
|
383
|
+
let xLimit = 0;
|
|
384
|
+
let yLimit = 0;
|
|
385
|
+
let rBoundary = rowSpan+row-1;
|
|
386
|
+
let cBoundary = colSpan+col-1;
|
|
387
|
+
|
|
388
|
+
if(rBoundary>=this.rows){
|
|
389
|
+
rBoundary = this.rows-1;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
if(cBoundary>=this.cols){
|
|
393
|
+
cBoundary = this.cols-1;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
for(let i=row+1; i<=rBoundary; i++){
|
|
397
|
+
if(this.grid[i][col]==null){
|
|
398
|
+
yLimit++;
|
|
399
|
+
} else {
|
|
400
|
+
console.log("can't expand beyond row ",row+yLimit," since there's a non-null element in row ",row+yLimit+1);
|
|
401
|
+
break;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
let breakFlag=false;
|
|
406
|
+
for(let j=col+1; j<=cBoundary; j++){
|
|
407
|
+
xLimit++;
|
|
408
|
+
for(let i=row; i<=yLimit+row; i++){
|
|
409
|
+
if(this.grid && this.grid[i][j]!=null){
|
|
410
|
+
if(xLimit>0){
|
|
411
|
+
xLimit--;
|
|
412
|
+
console.log("can't expand beyond col ",col+xLimit," since there's a non-null element in col ",col+xLimit+1);
|
|
413
|
+
}
|
|
414
|
+
breakFlag=true;
|
|
415
|
+
break;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
if(breakFlag){
|
|
419
|
+
break;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
let w=0;
|
|
424
|
+
let h=0;
|
|
425
|
+
for(let i=row; i<=row+yLimit; i++){
|
|
426
|
+
if(this.alwaysShowBanner){
|
|
427
|
+
h += (this.rowWeights[i]/this.totalRowWeight) * (this.height - this.bannerHeight - 2*this.pady);
|
|
428
|
+
} else {
|
|
429
|
+
h += (this.rowWeights[i]/this.totalRowWeight) * (this.height - 2*this.pady);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
for(let j=col; j<=col+xLimit; j++){
|
|
434
|
+
w += (this.colWeights[j]/this.totalColWeight) * (this.width - 2*this.padx);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
for(let i=row; i<=row+yLimit; i++){
|
|
438
|
+
for(let j=col; j<=col+xLimit; j++){
|
|
439
|
+
if(this.grid[i][j]==null){
|
|
440
|
+
this.grid[i][j]="taken";
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
this.grid[row][col][0].width = w - this.grid[row][col][3] - this.grid[row][col][4];
|
|
446
|
+
this.grid[row][col][0].height = h - this.grid[row][col][5] - this.grid[row][col][6];
|
|
447
|
+
this.grid[row][col][1] = yLimit+1;
|
|
448
|
+
this.grid[row][col][2] = xLimit+1;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Shows the frame banner and adjusts layout
|
|
453
|
+
*/
|
|
454
|
+
showBanner(){
|
|
455
|
+
this.adjustHeight(this.y + (this.bannerHeight) + this.pady, this.height - (this.bannerHeight) - 2*(this.pady));
|
|
456
|
+
this.isBannerShown=true;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Hides the frame banner and adjusts layout
|
|
461
|
+
*/
|
|
462
|
+
hideBanner(){
|
|
463
|
+
this.adjustHeight(this.y + this.pady, this.height-2*(this.pady));
|
|
464
|
+
this.isBannerShown=false;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Updates child component positions during frame movement
|
|
469
|
+
* @param {number} xDiff - X position difference
|
|
470
|
+
* @param {number} yDiff - Y position difference
|
|
471
|
+
*/
|
|
472
|
+
updatePosUtil(xDiff, yDiff){
|
|
473
|
+
for(let i=0; i<this.rows; i++){
|
|
474
|
+
for(let j=0; j<this.cols; j++){
|
|
475
|
+
if(this.grid && this.grid[i][j]!=null && this.grid[i][j]!="taken"){
|
|
476
|
+
this.grid[i][j][0].x -= xDiff;
|
|
477
|
+
this.grid[i][j][0].y -= yDiff;
|
|
478
|
+
if(this.grid[i][j][0].type=="Frame"){
|
|
479
|
+
this.grid[i][j][0].updatePosUtil(xDiff, yDiff);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Renders the grid frame and all child components
|
|
488
|
+
*/
|
|
489
|
+
show(){
|
|
490
|
+
|
|
491
|
+
//shadow
|
|
492
|
+
if(this.enableShadow){
|
|
493
|
+
this.drawShadow();
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
//applying background color
|
|
497
|
+
if(this.backgroundColor!=null){
|
|
498
|
+
push();
|
|
499
|
+
noStroke();
|
|
500
|
+
fill(this.backgroundColor);
|
|
501
|
+
rect(this.x, this.y, this.width, this.height, this.cornerRadius);
|
|
502
|
+
pop();
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
//applying clipping mask
|
|
506
|
+
push();
|
|
507
|
+
beginClip();
|
|
508
|
+
rect(this.x, this.y, this.width, this.height, this.cornerRadius);
|
|
509
|
+
endClip();
|
|
510
|
+
|
|
511
|
+
//displaying all the child elements
|
|
512
|
+
for(let i=0; i<this.rows; i++){
|
|
513
|
+
for(let j=0; j<this.cols; j++){
|
|
514
|
+
if(this.grid && this.grid[i][j]!=null && this.grid[i][j]!="taken"){
|
|
515
|
+
this.grid[i][j][0].show();
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
//showing the top banner
|
|
521
|
+
if(this.alwaysShowBanner || (this.enableReposition && this.isBannerShown==true)){
|
|
522
|
+
noStroke();
|
|
523
|
+
fill(0);
|
|
524
|
+
rect(this.x, this.y, this.width, this.bannerHeight);
|
|
525
|
+
|
|
526
|
+
fill(255);
|
|
527
|
+
ellipse(this.x+this.width/2,
|
|
528
|
+
this.y+(this.bannerHeight)/2,
|
|
529
|
+
(this.bannerHeight)/4,
|
|
530
|
+
(this.bannerHeight)/4);
|
|
531
|
+
ellipse(this.x+this.width/2 - (this.bannerHeight)/2,
|
|
532
|
+
this.y+(this.bannerHeight)/2, (this.bannerHeight)/4,
|
|
533
|
+
(this.bannerHeight)/4);
|
|
534
|
+
ellipse(this.x+this.width/2 + (this.bannerHeight)/2,
|
|
535
|
+
this.y+(this.bannerHeight)/2,
|
|
536
|
+
(this.bannerHeight)/4,
|
|
537
|
+
(this.bannerHeight)/4);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
pop();
|
|
541
|
+
|
|
542
|
+
//showing the border
|
|
543
|
+
if(this.borderColor!=null){
|
|
544
|
+
push();
|
|
545
|
+
stroke(this.borderColor);
|
|
546
|
+
strokeWeight(this.borderWidth);
|
|
547
|
+
noFill();
|
|
548
|
+
rect(this.x, this.y, this.width, this.height, this.cornerRadius);
|
|
549
|
+
pop();
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
//highlighting the relevant border if cursor is sufficiently near to it
|
|
553
|
+
// if(this.enableResizing && this.nearestBorder!=null){
|
|
554
|
+
// this.showHighlightedBorder();
|
|
555
|
+
// }
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Prints grid structure to console for debugging
|
|
560
|
+
*/
|
|
561
|
+
printGrid(){
|
|
562
|
+
for(let i=0; i<this.rows; i++){
|
|
563
|
+
let row = "";
|
|
564
|
+
for(let j=0; j<this.cols; j++){
|
|
565
|
+
if(this.grid[i][j]){
|
|
566
|
+
row += "* ";
|
|
567
|
+
} else {
|
|
568
|
+
row += "_ ";
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
console.log(row);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
}
|