Subversion Repositories Kolibri OS

Rev

Rev 9671 | Rev 9731 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8728 leency 1
(*
9628 akron1 2
    Copyright 2021, 2022 Anton Krotov
8728 leency 3
 
4
    This file is part of CEdit.
5
 
6
    CEdit is free software: you can redistribute it and/or modify
7
    it under the terms of the GNU General Public License as published by
8
    the Free Software Foundation, either version 3 of the License, or
9
    (at your option) any later version.
10
 
11
    CEdit is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
15
 
16
    You should have received a copy of the GNU General Public License
17
    along with CEdit. If not, see .
18
*)
19
 
20
MODULE Menu;
21
 
22
IMPORT
9730 akron1 23
    SYSTEM, G := Graph, List, K := KolibriOS, U := Utils;
8728 leency 24
 
25
CONST
9671 akron1 26
    itemHeight = 22;
8728 leency 27
    fontWidth = 8;
28
 
9187 akron1 29
    MainMenuHeight* = K.fontHeight + 7;
9522 akron1 30
	MainMenuX* = 3;
9187 akron1 31
 
8728 leency 32
    RIGHT = 16;
33
    LEFT = 16;
34
    TOP = 1;
35
 
9174 akron1 36
    maxLEVEL = 1;
37
 
8728 leency 38
    backColor = 0F0F0F0H;
39
    foreColor = 0;
40
    selBackColor = 091C9F7H;
41
    selForeColor = 0;
42
    disBackColor = backColor;
43
    disForeColor = 808080H;
44
    disSelBackColor = 0E4E4E4H;
45
    disSelForeColor = disForeColor;
46
 
9648 akron1 47
	SHIFT* = 256;
48
	CTRL*  = 512;
8728 leency 49
 
9648 akron1 50
 
8728 leency 51
TYPE
52
 
9187 akron1 53
	tMainItem* = POINTER TO descMainItem;
54
 
55
    tMain* = POINTER TO RECORD (List.tList)
9730 akron1 56
    	id: INTEGER;
57
    	canvas: G.tCanvas
9187 akron1 58
    END;
59
 
8728 leency 60
    tMenu* = POINTER TO RECORD
61
        tid*: INTEGER;
9187 akron1 62
        active*, keyboard: BOOLEAN;
9174 akron1 63
        parent*, child: tMenu;
9730 akron1 64
        mainTID: INTEGER;
9187 akron1 65
        mainID: INTEGER;
9671 akron1 66
        x*, winX, winY, width*, height*: INTEGER;
8728 leency 67
        selItem, cliItem: INTEGER;
68
 
69
        font: G.tFont;
70
        canvas: G.tCanvas;
71
 
9648 akron1 72
        items: List.tList
8728 leency 73
    END;
74
 
9174 akron1 75
    tItem* = POINTER TO RECORD (List.tItem)
76
        id*, check: INTEGER;
77
        text: ARRAY 32 OF WCHAR;
78
        enabled, delim: BOOLEAN;
79
        child: tMenu
80
    END;
81
 
9187 akron1 82
    descMainItem = RECORD (List.tItem)
83
        id*, x: INTEGER;
84
        text: ARRAY 32 OF WCHAR;
85
        menu*: tMenu;
9730 akron1 86
        main: tMain;
87
        selected: BOOLEAN
9187 akron1 88
    END;
89
 
9648 akron1 90
    tShortcut = POINTER TO RECORD (List.tItem)
91
    	key, MenuItem: INTEGER
92
    END;
93
 
9174 akron1 94
    tProc = PROCEDURE;
8728 leency 95
 
96
VAR
9648 akron1 97
	MenuItem*: INTEGER;
9522 akron1 98
    stack: ARRAY maxLEVEL + 1, 2500 OF INTEGER;
9174 akron1 99
    TIDs: ARRAY maxLEVEL + 1 OF INTEGER;
100
    resetTimer: tProc;
101
    _open: PROCEDURE (m: tMenu; x, y: INTEGER);
9648 akron1 102
    shortcuts: List.tList;
9175 akron1 103
(*
104
    backColor, foreColor, selBackColor, selForeColor,
105
    disBackColor, disForeColor, disSelBackColor, disSelForeColor: INTEGER;
106
*)
8728 leency 107
 
9187 akron1 108
PROCEDURE AddMainItem* (main: tMain; text: ARRAY OF WCHAR; menu: tMenu);
109
VAR
110
	item, prev: tMainItem;
111
BEGIN
112
	NEW(item);
113
	item.id := main.id + main.count;
114
	COPY(text, item.text);
115
	item.menu := menu;
116
	item.main := main;
9730 akron1 117
	item.selected := FALSE;
9187 akron1 118
	menu.mainID := item.id;
119
	List.append(main, item);
120
	prev := item.prev(tMainItem);
121
	IF prev # NIL THEN
122
		item.x := prev.x + LENGTH(prev.text)*fontWidth + 9
123
	ELSE
9457 akron1 124
		item.x := MainMenuX
9671 akron1 125
	END;
9730 akron1 126
	menu.x := item.x;
127
	G.destroy(main.canvas);
128
	main.canvas := G.CreateCanvas(item.x + LENGTH(item.text)*fontWidth + 9, MainMenuHeight);
129
	G.SetFont(main.canvas, G.fonts[1])
9187 akron1 130
END AddMainItem;
131
 
132
 
133
PROCEDURE CreateMain* (id: INTEGER): tMain;
134
VAR
135
	res: tMain;
136
	list: List.tList;
137
BEGIN
138
	NEW(res);
139
	res.id := id;
9730 akron1 140
	res.canvas := NIL;
9187 akron1 141
	list := List.create(res)
142
	RETURN res
143
END CreateMain;
144
 
145
 
146
PROCEDURE drawMainItem (item: tMainItem);
147
VAR
148
    menuColor, textColor, n: INTEGER;
9730 akron1 149
    canvas: G.tCanvas;
9187 akron1 150
BEGIN
151
    IF item.menu.tid # 0 THEN
9628 akron1 152
        menuColor := K.colors.work_text;
153
        textColor := K.colors.work
9187 akron1 154
    ELSE
9730 akron1 155
    	IF item.selected THEN
156
	        menuColor := K.colors.button;
157
	        textColor := K.colors.button_text
158
    	ELSE
159
	        menuColor := K.colors.work;
160
	        textColor := K.colors.work_text
161
        END
9187 akron1 162
    END;
163
    n := LENGTH(item.text);
9730 akron1 164
    canvas := item.main.canvas;
165
    G.SetColor(canvas, menuColor);
166
    G.FillRect(canvas, item.x, 0, item.x + n*fontWidth + 2, MainMenuHeight - 1);
167
    G.SetTextColor(canvas, textColor);
168
    G.SetBkColor(canvas, menuColor);
169
    G.TextOut2(canvas, item.x + 1, (MainMenuHeight - K.fontHeight) DIV 2 + 1, item.text, n);
9187 akron1 170
END drawMainItem;
171
 
172
 
173
PROCEDURE DrawMain* (main: tMain);
174
VAR
9730 akron1 175
	item: tMainItem;
9187 akron1 176
BEGIN
9730 akron1 177
	G.SetColor(main.canvas, K.colors.work);
178
	G.clear(main.canvas);
179
	item := main.first(tMainItem);
9187 akron1 180
	WHILE item # NIL DO
9730 akron1 181
		drawMainItem(item);
182
		K.CreateButton(item.id + ORD({30}), item.x, 0, LENGTH(item.text)*fontWidth + 2, MainMenuHeight, 0, "");
183
		item := item.next(tMainItem)
184
	END;
185
	G.DrawCanvas(main.canvas, 0, 0)
9187 akron1 186
END DrawMain;
187
 
188
 
9730 akron1 189
PROCEDURE MouseMove* (main: tMain; x, y: INTEGER);
190
VAR
191
	item: tMainItem;
192
BEGIN
193
	item := main.first(tMainItem);
194
	WHILE item # NIL DO
195
		item.selected :=
196
			U.between(item.x, x, item.x + LENGTH(item.text)*fontWidth - 1) &
197
				U.between(0, y, MainMenuHeight - 1);
198
		drawMainItem(item);
199
		item := item.next(tMainItem)
200
	END;
201
	G.DrawCanvas(main.canvas, 0, 0)
202
END MouseMove;
203
 
204
 
9187 akron1 205
PROCEDURE getMainID (m: tMenu): INTEGER;
206
BEGIN
207
	WHILE m.parent # NIL DO
208
		m := m.parent
209
	END
210
	RETURN m.mainID
211
END getMainID;
212
 
213
 
214
PROCEDURE ClickMain* (main: tMain; btn: INTEGER): tMenu;
215
VAR
216
	item: List.tItem;
217
	res: tMenu;
218
BEGIN
219
	item := List.getItem(main, btn - main.id);
220
	IF item # NIL THEN
221
		res := item(tMainItem).menu
222
	ELSE
223
		res := NIL
224
	END
225
	RETURN res
226
END ClickMain;
227
 
228
 
9174 akron1 229
PROCEDURE isSender* (tid: INTEGER): BOOLEAN;
230
VAR
231
	i: INTEGER;
232
BEGIN
233
	i := 0;
234
	WHILE (i <= maxLEVEL) & (TIDs[i] # tid) DO
235
		INC(i)
236
	END
237
	RETURN i <= maxLEVEL
238
END isSender;
239
 
240
 
8728 leency 241
PROCEDURE exit (m: tMenu);
242
BEGIN
9187 akron1 243
    m.active := FALSE;
244
   	resetTimer;
8728 leency 245
    m.tid := 0;
246
    K.Exit
247
END exit;
248
 
249
 
9187 akron1 250
PROCEDURE escape (m: tMenu);
251
BEGIN
252
    m.active := FALSE;
253
    IF m.parent = NIL THEN
254
    	resetTimer
255
    END;
256
    m.tid := 0;
257
    K.Exit
258
END escape;
259
 
260
 
8728 leency 261
PROCEDURE repaint (m: tMenu);
262
VAR
9628 akron1 263
    y, i, X, Y, Y1: INTEGER;
8728 leency 264
    item: tItem;
265
    BkColor, TextColor: INTEGER;
266
    canvas: G.tCanvas;
267
 
268
BEGIN
9175 akron1 269
(*
270
    backColor := K.winColor;
271
    foreColor := K.textColor;
272
    selBackColor := K.btnColor;
273
    selForeColor := K.btnTextColor;
274
 
275
    disBackColor := backColor;
276
    disForeColor := K.darkColor;
277
    disSelBackColor := K.lightColor;
278
    disSelForeColor := disForeColor;
279
*)
8728 leency 280
    canvas := m.canvas;
281
    G.SetColor(canvas, backColor);
282
    G.clear(canvas);
9180 akron1 283
    G.SetColor(canvas, foreColor);
8728 leency 284
    G.Rect(canvas, 0, 0, m.width, m.height);
285
    y := TOP;
286
    i := 0;
287
    item := m.items.first(tItem);
288
    WHILE item # NIL DO
289
        IF item.enabled THEN
290
            IF i # m.selItem THEN
291
                BkColor := backColor;
292
                TextColor := foreColor
293
            ELSE
294
                BkColor := selBackColor;
295
                TextColor := selForeColor
296
            END
297
        ELSE
298
            IF i # m.selItem THEN
299
                BkColor := disBackColor;
300
                TextColor := disForeColor
301
            ELSE
302
                BkColor := disSelBackColor;
303
                TextColor := disSelForeColor
304
            END
305
        END;
9671 akron1 306
        Y := y + (itemHeight - 16) DIV 2;
8728 leency 307
        G.SetColor(canvas, BkColor);
9671 akron1 308
        G.FillRect(canvas, 1, y, m.width - 1, y + itemHeight - 4);
8728 leency 309
        G.SetTextColor(canvas, TextColor);
310
        G.SetBkColor(canvas, BkColor);
9448 akron1 311
        G.TextOut2(canvas, LEFT, Y - 2, item.text, LENGTH(item.text));
8728 leency 312
 
9174 akron1 313
        G.SetColor(canvas, TextColor);
8728 leency 314
        IF item.check = 1 THEN
9628 akron1 315
            G.DLine(canvas, 4,  7, Y + 5, -1);
316
            G.DLine(canvas, 4,  7, Y + 6, -1);
317
            G.DLine(canvas, 7, 12, Y + 8,  1);
318
            G.DLine(canvas, 7, 12, Y + 9,  1)
8728 leency 319
        ELSIF item.check = 2 THEN
9671 akron1 320
            Y1 := y + itemHeight DIV 2 - 2;
9628 akron1 321
            G.FillRect(canvas, 7, Y1 - 2,  9, Y1 + 2);
322
            G.FillRect(canvas, 6, Y1 - 1, 10, Y1 + 1)
8728 leency 323
        END;
324
 
9174 akron1 325
        IF item.child # NIL THEN
326
            X := m.width - 9;
9448 akron1 327
        	G.Triangle(canvas, X, Y + 2, X, Y + 10, G.triRight)
9174 akron1 328
        END;
329
 
9671 akron1 330
        INC(y, itemHeight);
8728 leency 331
        IF item.delim THEN
9180 akron1 332
            G.SetColor(canvas, foreColor);
8728 leency 333
            G.HLine(canvas, y - 2, 1, m.width - 1)
334
        END;
335
        INC(i);
336
        item := item.next(tItem)
337
    END;
338
    G.DrawCanvas(canvas, 0, 0)
339
END repaint;
340
 
341
 
342
PROCEDURE draw_window (m: tMenu);
343
BEGIN
344
    K.BeginDraw;
345
    K.CreateWindow(m.winX, m.winY, m.width, m.height, 0, 61H, 0, 1, "");
346
    repaint(m);
347
    K.EndDraw
348
END draw_window;
349
 
350
 
9174 akron1 351
PROCEDURE close* (m: tMenu);
9187 akron1 352
VAR
353
	temp: INTEGER;
9174 akron1 354
BEGIN
355
    IF (m # NIL) & (m.tid # 0) THEN
356
    	IF m.child # NIL THEN
357
    		close(m.child);
358
    		m.child := NIL
359
    	END;
9187 akron1 360
    	temp := m.tid;
361
    	m.tid := 0;
362
        K.ExitID(temp);
9174 akron1 363
        m.active := FALSE
364
    END
365
END close;
366
 
367
 
9648 akron1 368
PROCEDURE SetItem* (id: INTEGER);
369
BEGIN
370
	MenuItem := id
371
END SetItem;
372
 
373
 
8728 leency 374
PROCEDURE click (m: tMenu; i: INTEGER);
375
VAR
376
    item: List.tItem;
9174 akron1 377
    p: tMenu;
9187 akron1 378
    id: INTEGER;
8728 leency 379
BEGIN
9187 akron1 380
	id := -1;
381
	IF i < 0 THEN
382
		id := i
383
	ELSE
384
	    item := List.getItem(m.items, i);
385
	    IF (item # NIL) & item(tItem).enabled & (item(tItem).child = NIL) THEN
386
	    	id := item(tItem).id
387
	    END
388
    END;
389
    IF id # -1 THEN
9648 akron1 390
    	SetItem(id);
9187 akron1 391
	    p := m.parent;
392
	   	WHILE p # NIL DO
393
	   		p.child := NIL;
394
	   		close(p);
395
	   		p := p.parent
396
	   	END;
397
	   	exit(m)
398
   	END
8728 leency 399
END click;
400
 
401
 
9174 akron1 402
PROCEDURE opened* (m: tMenu): BOOLEAN;
403
    RETURN m.tid # 0
404
END opened;
405
 
406
 
407
PROCEDURE isActive (m: tMenu): BOOLEAN;
408
	RETURN (m # NIL) & ((m.tid # 0) & m.active OR isActive(m.child))
409
END isActive;
410
 
411
 
412
PROCEDURE closeChild (m: tMenu);
413
BEGIN
414
	IF m.child # NIL THEN
415
		close(m.child);
416
		m.child := NIL
417
	END
418
END closeChild;
419
 
420
 
9187 akron1 421
PROCEDURE submenu (m: tMenu; keyboard: BOOLEAN): BOOLEAN;
9174 akron1 422
VAR
423
	item: List.tItem;
9187 akron1 424
	res: BOOLEAN;
9174 akron1 425
BEGIN
9187 akron1 426
	res := FALSE;
9174 akron1 427
    item := List.getItem(m.items, m.selItem);
428
    IF (item # NIL) & item(tItem).enabled & (item(tItem).child # NIL) THEN
9187 akron1 429
    	res := TRUE;
9174 akron1 430
    	IF ~opened(item(tItem).child) THEN
431
    		closeChild(m);
9187 akron1 432
    		item(tItem).child.keyboard := keyboard;
9671 akron1 433
    		_open(item(tItem).child, m.winX + m.width - 2, m.winY + m.selItem*itemHeight);
9187 akron1 434
    		m.child := item(tItem).child;
9174 akron1 435
    	END
436
    ELSE
437
    	closeChild(m)
438
    END
9187 akron1 439
    RETURN res
9174 akron1 440
END submenu;
441
 
442
 
9648 akron1 443
PROCEDURE getShortcut (key: INTEGER): BOOLEAN;
444
VAR
445
	item: tShortcut;
446
	res: INTEGER;
447
BEGIN
448
	item := shortcuts.first(tShortcut);
449
	WHILE (item # NIL) & (item.key # key) DO
450
		item := item.next(tShortcut)
451
	END;
452
	IF item # NIL THEN
453
		res := item.MenuItem
454
	ELSE
455
		res := 0
456
	END;
457
	SetItem(res)
458
	RETURN res # 0
459
END getShortcut;
460
 
461
 
8728 leency 462
PROCEDURE [stdcall] window (m: tMenu);
463
VAR
464
    x, y: INTEGER;
9448 akron1 465
    msState: SET;
9187 akron1 466
    key, temp: INTEGER;
467
    shift, ctrl: BOOLEAN;
8728 leency 468
BEGIN
9187 akron1 469
    m.selItem := ORD(m.keyboard) - 1;
8728 leency 470
    m.cliItem := -1;
9187 akron1 471
    m.keyboard := FALSE;
8728 leency 472
    K.SetEventsMask({0, 1, 5});
473
    WHILE TRUE DO
9448 akron1 474
        CASE K.EventTimeout(100) OF
475
        |0:
8728 leency 476
        |1:
477
            draw_window(m)
478
        |2:
9187 akron1 479
        	K.getKBState(shift, ctrl);
9648 akron1 480
            key := K.GetKey() DIV 65536;
481
		    IF shift THEN
482
		    	INC(key, SHIFT)
483
		    END;
484
		    IF ctrl THEN
485
		    	INC(key, CTRL)
486
		    END;
487
 
488
        	CASE key OF
489
            |72:
490
                m.selItem := (m.selItem - 1) MOD m.items.count
491
            |80:
492
                m.selItem := (m.selItem + 1) MOD m.items.count
493
            |28:
494
                IF m.selItem >= 0 THEN
495
                    click(m, m.selItem)
496
                END;
497
                m.cliItem := -1
498
            |77:
499
                IF ~submenu(m, TRUE) THEN
500
                	click(m, -(getMainID(m) + 1))
501
                END;
502
                m.cliItem := -1
503
            |75:
504
            	IF m.parent # NIL THEN
505
                	escape(m)
506
            	ELSE
507
            		click(m, -(getMainID(m) - 1))
508
                END;
509
                m.cliItem := -1
510
            |1:
511
            	escape(m)
512
            ELSE
513
	            IF getShortcut(key) THEN
9187 akron1 514
	            	IF m.parent # NIL THEN
9648 akron1 515
	            		temp := m.parent.tid;
516
	            		m.parent.tid := 0;
517
	            		K.ExitID(temp)
518
	            	END;
519
	                exit(m)
520
	            END
8728 leency 521
            END;
522
            repaint(m)
523
        |6:
9208 akron1 524
        	K.mouse(msState, x, y);
9730 akron1 525
        	temp := (x + m.winX)*65536 + (y + m.winY);
526
        	K.SendIPC(m.mainTID, SYSTEM.ADR(temp), SYSTEM.SIZE(INTEGER));
8728 leency 527
            IF (0 <= x) & (x < m.width) & (0 <= y) & (y < m.height) THEN
9174 akron1 528
            	m.active := TRUE;
9671 akron1 529
                m.selItem := (y - TOP) DIV itemHeight;
8728 leency 530
                IF 8 IN msState THEN
9671 akron1 531
                    m.cliItem := (y - TOP) DIV itemHeight
8728 leency 532
                END;
533
                IF 16 IN msState THEN
534
                    IF m.cliItem = m.selItem THEN
535
                        click(m, m.cliItem)
536
                    END;
537
                    m.cliItem := -1
538
                END
539
            ELSE
9174 akron1 540
            	m.active := FALSE;
8728 leency 541
                m.cliItem := -1;
9174 akron1 542
                IF ({8, 9, 10, 16} * msState # {}) & ~isActive(m.child) THEN
8728 leency 543
                    exit(m)
544
                END
545
            END;
9174 akron1 546
            repaint(m);
9187 akron1 547
            IF submenu(m, FALSE) THEN END
8728 leency 548
        END
549
    END
550
END window;
551
 
552
 
9174 akron1 553
PROCEDURE level (m: tMenu): INTEGER;
554
VAR
555
	res: INTEGER;
556
BEGIN
557
	res := 0;
558
	WHILE m.parent # NIL DO
559
		INC(res);
560
		m := m.parent
561
	END
562
	RETURN res
563
END level;
564
 
565
 
566
PROCEDURE open* (m: tMenu; x, y: INTEGER);
567
VAR
568
	L: INTEGER;
569
BEGIN
570
    IF m.tid = 0 THEN
571
        L := level(m);
9448 akron1 572
        IF K.GetThreadSlot(TIDs[L]) = 0 THEN
9187 akron1 573
        	m.winX := x;
574
        	m.winY := y;
575
	        SYSTEM.PUT(SYSTEM.ADR(stack[L][LEN(stack[0]) - 1]), m);
576
    	    m.tid := K.CreateThread(SYSTEM.ADR(window), stack[L]);
577
        	TIDs[L] := m.tid
578
        END
9174 akron1 579
    END
580
END open;
581
 
582
 
8728 leency 583
PROCEDURE AddMenuItem* (items: List.tList; id: INTEGER; s: ARRAY OF WCHAR);
584
VAR
585
    item: tItem;
586
BEGIN
587
    NEW(item);
588
    item.id := id;
589
    item.text := s;
590
    item.enabled := TRUE;
591
    item.delim := FALSE;
9174 akron1 592
    item.child := NIL;
8728 leency 593
    List.append(items, item);
594
END AddMenuItem;
595
 
596
 
597
PROCEDURE delimiter* (items: List.tList);
598
BEGIN
599
    items.last(tItem).delim := TRUE
600
END delimiter;
601
 
602
 
9174 akron1 603
PROCEDURE child* (items: List.tList; menu: tMenu);
604
BEGIN
605
    items.last(tItem).child := menu
606
END child;
607
 
608
 
8728 leency 609
PROCEDURE getItem (m: tMenu; id: INTEGER): tItem;
610
VAR
611
    item: tItem;
612
BEGIN
613
    item := m.items.first(tItem);
614
    WHILE (item # NIL) & (item.id # id) DO
615
        item := item.next(tItem)
616
    END
617
    RETURN item
618
END getItem;
619
 
620
 
621
PROCEDURE setEnabled* (m: tMenu; id: INTEGER; value: BOOLEAN);
622
VAR
623
    item: tItem;
624
BEGIN
625
    item := getItem(m, id);
626
    IF item # NIL THEN
627
        item.enabled := value
628
    END
629
END setEnabled;
630
 
631
 
9182 akron1 632
PROCEDURE check* (m: tMenu; id: INTEGER; value: BOOLEAN);
8728 leency 633
VAR
634
    item: tItem;
635
BEGIN
636
    item := getItem(m, id);
637
    IF item # NIL THEN
9182 akron1 638
        item.check := ORD(value)
8728 leency 639
    END
9182 akron1 640
END check;
8728 leency 641
 
642
 
9182 akron1 643
PROCEDURE option* (m: tMenu; id: INTEGER; value: BOOLEAN);
644
VAR
645
    item: tItem;
646
BEGIN
647
    item := getItem(m, id);
648
    IF item # NIL THEN
649
        item.check := ORD(value)*2
650
    END
651
END option;
652
 
653
 
8728 leency 654
PROCEDURE isEnabled* (m: tMenu; id: INTEGER): BOOLEAN;
655
VAR
656
    item: tItem;
657
BEGIN
658
    item := getItem(m, id)
659
    RETURN (item # NIL) & item.enabled
660
END isEnabled;
661
 
662
 
9730 akron1 663
PROCEDURE create* (items: List.tList; mainTID: INTEGER): tMenu;
8728 leency 664
VAR
665
    m: tMenu;
666
    maxLength: INTEGER;
667
    item: tItem;
668
BEGIN
669
    NEW(m);
670
    m.tid := 0;
9174 akron1 671
    m.active := FALSE;
672
    m.parent := NIL;
673
    m.child := NIL;
9187 akron1 674
    m.mainID := 0;
9730 akron1 675
    m.mainTID := mainTID;
8728 leency 676
    m.items  := items;
677
    maxLength := 0;
678
    item := items.first(tItem);
679
    WHILE item # NIL DO
680
        maxLength := MAX(maxLength, LENGTH(item.text));
681
        item := item.next(tItem)
682
    END;
683
    m.width  := maxLength*fontWidth + LEFT + RIGHT;
9671 akron1 684
    m.height := items.count*itemHeight - 2;
685
    m.font := G.fonts[1];
8728 leency 686
    m.canvas := G.CreateCanvas(m.width + 1, m.height + 1);
9671 akron1 687
    G.SetFont(m.canvas, m.font)
8728 leency 688
    RETURN m
689
END create;
690
 
9174 akron1 691
 
9648 akron1 692
PROCEDURE AddShortcut* (key, MenuItem: INTEGER);
693
VAR
694
	item: tShortcut;
695
BEGIN
696
	NEW(item);
697
	item.key := key;
698
	item.MenuItem := MenuItem;
699
	List.append(shortcuts, item)
700
END AddShortcut;
701
 
702
 
9174 akron1 703
PROCEDURE init* (_resetTimer: tProc);
704
VAR
705
	i: INTEGER;
706
BEGIN
9648 akron1 707
	SetItem(0);
708
	shortcuts := List.create(NIL);
9174 akron1 709
	resetTimer := _resetTimer;
710
	_open := open;
711
	FOR i := 0 TO maxLEVEL DO
712
		TIDs[i] := 0
713
	END
714
END init;
715
 
716
 
8728 leency 717
END Menu.