Subversion Repositories Kolibri OS

Rev

Rev 9731 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8728 leency 1
(*
9902 akron1 2
    Copyright 2021-2023 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
9731 akron1 148
	menuColor, textColor, n: INTEGER;
149
	canvas: G.tCanvas;
9187 akron1 150
BEGIN
9731 akron1 151
	IF item.selected OR (item.menu.tid # 0) THEN
152
		menuColor := K.colors.button;
153
		textColor := K.colors.button_text
154
	ELSE
155
		menuColor := K.colors.work;
156
		textColor := K.colors.work_text
157
	END;
158
	n := LENGTH(item.text);
159
	canvas := item.main.canvas;
160
	G.SetColor(canvas, menuColor);
161
	G.FillRect(canvas, item.x, 0, item.x + n*fontWidth + 2, MainMenuHeight - 1);
162
	G.SetTextColor(canvas, textColor);
163
	G.SetBkColor(canvas, menuColor);
164
	G.TextOut2(canvas, item.x + 1, (MainMenuHeight - K.fontHeight) DIV 2 + 1, item.text, n);
9187 akron1 165
END drawMainItem;
166
 
167
 
168
PROCEDURE DrawMain* (main: tMain);
169
VAR
9730 akron1 170
	item: tMainItem;
9187 akron1 171
BEGIN
9730 akron1 172
	G.SetColor(main.canvas, K.colors.work);
173
	G.clear(main.canvas);
174
	item := main.first(tMainItem);
9187 akron1 175
	WHILE item # NIL DO
9730 akron1 176
		drawMainItem(item);
177
		K.CreateButton(item.id + ORD({30}), item.x, 0, LENGTH(item.text)*fontWidth + 2, MainMenuHeight, 0, "");
178
		item := item.next(tMainItem)
179
	END;
180
	G.DrawCanvas(main.canvas, 0, 0)
9187 akron1 181
END DrawMain;
182
 
183
 
9730 akron1 184
PROCEDURE MouseMove* (main: tMain; x, y: INTEGER);
185
VAR
186
	item: tMainItem;
187
BEGIN
188
	item := main.first(tMainItem);
189
	WHILE item # NIL DO
190
		item.selected :=
9731 akron1 191
			U.between(item.x, x, item.x + LENGTH(item.text)*fontWidth + 1) &
9730 akron1 192
				U.between(0, y, MainMenuHeight - 1);
193
		drawMainItem(item);
194
		item := item.next(tMainItem)
195
	END;
196
	G.DrawCanvas(main.canvas, 0, 0)
197
END MouseMove;
198
 
199
 
9187 akron1 200
PROCEDURE getMainID (m: tMenu): INTEGER;
201
BEGIN
202
	WHILE m.parent # NIL DO
203
		m := m.parent
204
	END
205
	RETURN m.mainID
206
END getMainID;
207
 
208
 
209
PROCEDURE ClickMain* (main: tMain; btn: INTEGER): tMenu;
210
VAR
211
	item: List.tItem;
212
	res: tMenu;
213
BEGIN
214
	item := List.getItem(main, btn - main.id);
215
	IF item # NIL THEN
216
		res := item(tMainItem).menu
217
	ELSE
218
		res := NIL
219
	END
220
	RETURN res
221
END ClickMain;
222
 
223
 
9174 akron1 224
PROCEDURE isSender* (tid: INTEGER): BOOLEAN;
225
VAR
226
	i: INTEGER;
227
BEGIN
228
	i := 0;
229
	WHILE (i <= maxLEVEL) & (TIDs[i] # tid) DO
230
		INC(i)
231
	END
232
	RETURN i <= maxLEVEL
233
END isSender;
234
 
235
 
8728 leency 236
PROCEDURE exit (m: tMenu);
237
BEGIN
9187 akron1 238
    m.active := FALSE;
239
   	resetTimer;
8728 leency 240
    m.tid := 0;
9902 akron1 241
    G.destroy(m.canvas);
8728 leency 242
    K.Exit
243
END exit;
244
 
245
 
9187 akron1 246
PROCEDURE escape (m: tMenu);
247
BEGIN
248
    m.active := FALSE;
249
    IF m.parent = NIL THEN
250
    	resetTimer
251
    END;
252
    m.tid := 0;
9902 akron1 253
    G.destroy(m.canvas);
9187 akron1 254
    K.Exit
255
END escape;
256
 
257
 
8728 leency 258
PROCEDURE repaint (m: tMenu);
259
VAR
9628 akron1 260
    y, i, X, Y, Y1: INTEGER;
8728 leency 261
    item: tItem;
262
    BkColor, TextColor: INTEGER;
263
    canvas: G.tCanvas;
264
 
265
BEGIN
9175 akron1 266
(*
267
    backColor := K.winColor;
268
    foreColor := K.textColor;
269
    selBackColor := K.btnColor;
270
    selForeColor := K.btnTextColor;
271
 
272
    disBackColor := backColor;
273
    disForeColor := K.darkColor;
274
    disSelBackColor := K.lightColor;
275
    disSelForeColor := disForeColor;
276
*)
8728 leency 277
    canvas := m.canvas;
278
    G.SetColor(canvas, backColor);
279
    G.clear(canvas);
9180 akron1 280
    G.SetColor(canvas, foreColor);
8728 leency 281
    G.Rect(canvas, 0, 0, m.width, m.height);
282
    y := TOP;
283
    i := 0;
284
    item := m.items.first(tItem);
285
    WHILE item # NIL DO
286
        IF item.enabled THEN
287
            IF i # m.selItem THEN
288
                BkColor := backColor;
289
                TextColor := foreColor
290
            ELSE
291
                BkColor := selBackColor;
292
                TextColor := selForeColor
293
            END
294
        ELSE
295
            IF i # m.selItem THEN
296
                BkColor := disBackColor;
297
                TextColor := disForeColor
298
            ELSE
299
                BkColor := disSelBackColor;
300
                TextColor := disSelForeColor
301
            END
302
        END;
9671 akron1 303
        Y := y + (itemHeight - 16) DIV 2;
8728 leency 304
        G.SetColor(canvas, BkColor);
9671 akron1 305
        G.FillRect(canvas, 1, y, m.width - 1, y + itemHeight - 4);
8728 leency 306
        G.SetTextColor(canvas, TextColor);
307
        G.SetBkColor(canvas, BkColor);
9448 akron1 308
        G.TextOut2(canvas, LEFT, Y - 2, item.text, LENGTH(item.text));
8728 leency 309
 
9174 akron1 310
        G.SetColor(canvas, TextColor);
8728 leency 311
        IF item.check = 1 THEN
9628 akron1 312
            G.DLine(canvas, 4,  7, Y + 5, -1);
313
            G.DLine(canvas, 4,  7, Y + 6, -1);
314
            G.DLine(canvas, 7, 12, Y + 8,  1);
315
            G.DLine(canvas, 7, 12, Y + 9,  1)
8728 leency 316
        ELSIF item.check = 2 THEN
9671 akron1 317
            Y1 := y + itemHeight DIV 2 - 2;
9628 akron1 318
            G.FillRect(canvas, 7, Y1 - 2,  9, Y1 + 2);
319
            G.FillRect(canvas, 6, Y1 - 1, 10, Y1 + 1)
8728 leency 320
        END;
321
 
9174 akron1 322
        IF item.child # NIL THEN
323
            X := m.width - 9;
9448 akron1 324
        	G.Triangle(canvas, X, Y + 2, X, Y + 10, G.triRight)
9174 akron1 325
        END;
326
 
9671 akron1 327
        INC(y, itemHeight);
8728 leency 328
        IF item.delim THEN
9180 akron1 329
            G.SetColor(canvas, foreColor);
8728 leency 330
            G.HLine(canvas, y - 2, 1, m.width - 1)
331
        END;
332
        INC(i);
333
        item := item.next(tItem)
334
    END;
335
    G.DrawCanvas(canvas, 0, 0)
336
END repaint;
337
 
338
 
339
PROCEDURE draw_window (m: tMenu);
340
BEGIN
341
    K.BeginDraw;
342
    K.CreateWindow(m.winX, m.winY, m.width, m.height, 0, 61H, 0, 1, "");
343
    repaint(m);
344
    K.EndDraw
345
END draw_window;
346
 
347
 
9174 akron1 348
PROCEDURE close* (m: tMenu);
9187 akron1 349
VAR
350
	temp: INTEGER;
9174 akron1 351
BEGIN
352
    IF (m # NIL) & (m.tid # 0) THEN
353
    	IF m.child # NIL THEN
354
    		close(m.child);
355
    		m.child := NIL
356
    	END;
9187 akron1 357
    	temp := m.tid;
358
    	m.tid := 0;
9902 akron1 359
    	G.destroy(m.canvas);
9187 akron1 360
        K.ExitID(temp);
9174 akron1 361
        m.active := FALSE
362
    END
363
END close;
364
 
365
 
9648 akron1 366
PROCEDURE SetItem* (id: INTEGER);
367
BEGIN
368
	MenuItem := id
369
END SetItem;
370
 
371
 
8728 leency 372
PROCEDURE click (m: tMenu; i: INTEGER);
373
VAR
374
    item: List.tItem;
9174 akron1 375
    p: tMenu;
9187 akron1 376
    id: INTEGER;
8728 leency 377
BEGIN
9187 akron1 378
	id := -1;
379
	IF i < 0 THEN
380
		id := i
381
	ELSE
382
	    item := List.getItem(m.items, i);
383
	    IF (item # NIL) & item(tItem).enabled & (item(tItem).child = NIL) THEN
384
	    	id := item(tItem).id
385
	    END
386
    END;
387
    IF id # -1 THEN
9648 akron1 388
    	SetItem(id);
9187 akron1 389
	    p := m.parent;
390
	   	WHILE p # NIL DO
391
	   		p.child := NIL;
392
	   		close(p);
393
	   		p := p.parent
394
	   	END;
395
	   	exit(m)
396
   	END
8728 leency 397
END click;
398
 
399
 
9174 akron1 400
PROCEDURE opened* (m: tMenu): BOOLEAN;
401
    RETURN m.tid # 0
402
END opened;
403
 
404
 
405
PROCEDURE isActive (m: tMenu): BOOLEAN;
406
	RETURN (m # NIL) & ((m.tid # 0) & m.active OR isActive(m.child))
407
END isActive;
408
 
409
 
410
PROCEDURE closeChild (m: tMenu);
411
BEGIN
412
	IF m.child # NIL THEN
413
		close(m.child);
414
		m.child := NIL
415
	END
416
END closeChild;
417
 
418
 
9187 akron1 419
PROCEDURE submenu (m: tMenu; keyboard: BOOLEAN): BOOLEAN;
9174 akron1 420
VAR
421
	item: List.tItem;
9187 akron1 422
	res: BOOLEAN;
9174 akron1 423
BEGIN
9187 akron1 424
	res := FALSE;
9174 akron1 425
    item := List.getItem(m.items, m.selItem);
426
    IF (item # NIL) & item(tItem).enabled & (item(tItem).child # NIL) THEN
9187 akron1 427
    	res := TRUE;
9174 akron1 428
    	IF ~opened(item(tItem).child) THEN
429
    		closeChild(m);
9187 akron1 430
    		item(tItem).child.keyboard := keyboard;
9671 akron1 431
    		_open(item(tItem).child, m.winX + m.width - 2, m.winY + m.selItem*itemHeight);
9187 akron1 432
    		m.child := item(tItem).child;
9174 akron1 433
    	END
434
    ELSE
435
    	closeChild(m)
436
    END
9187 akron1 437
    RETURN res
9174 akron1 438
END submenu;
439
 
440
 
9648 akron1 441
PROCEDURE getShortcut (key: INTEGER): BOOLEAN;
442
VAR
443
	item: tShortcut;
444
	res: INTEGER;
445
BEGIN
446
	item := shortcuts.first(tShortcut);
447
	WHILE (item # NIL) & (item.key # key) DO
448
		item := item.next(tShortcut)
449
	END;
450
	IF item # NIL THEN
451
		res := item.MenuItem
452
	ELSE
453
		res := 0
454
	END;
455
	SetItem(res)
456
	RETURN res # 0
457
END getShortcut;
458
 
459
 
8728 leency 460
PROCEDURE [stdcall] window (m: tMenu);
461
VAR
462
    x, y: INTEGER;
9448 akron1 463
    msState: SET;
9187 akron1 464
    key, temp: INTEGER;
465
    shift, ctrl: BOOLEAN;
8728 leency 466
BEGIN
9187 akron1 467
    m.selItem := ORD(m.keyboard) - 1;
8728 leency 468
    m.cliItem := -1;
9187 akron1 469
    m.keyboard := FALSE;
8728 leency 470
    K.SetEventsMask({0, 1, 5});
471
    WHILE TRUE DO
9448 akron1 472
        CASE K.EventTimeout(100) OF
473
        |0:
8728 leency 474
        |1:
475
            draw_window(m)
476
        |2:
9187 akron1 477
        	K.getKBState(shift, ctrl);
9648 akron1 478
            key := K.GetKey() DIV 65536;
479
		    IF shift THEN
480
		    	INC(key, SHIFT)
481
		    END;
482
		    IF ctrl THEN
483
		    	INC(key, CTRL)
484
		    END;
485
 
486
        	CASE key OF
487
            |72:
488
                m.selItem := (m.selItem - 1) MOD m.items.count
489
            |80:
490
                m.selItem := (m.selItem + 1) MOD m.items.count
491
            |28:
492
                IF m.selItem >= 0 THEN
493
                    click(m, m.selItem)
494
                END;
495
                m.cliItem := -1
496
            |77:
497
                IF ~submenu(m, TRUE) THEN
498
                	click(m, -(getMainID(m) + 1))
499
                END;
500
                m.cliItem := -1
501
            |75:
502
            	IF m.parent # NIL THEN
503
                	escape(m)
504
            	ELSE
505
            		click(m, -(getMainID(m) - 1))
506
                END;
507
                m.cliItem := -1
508
            |1:
509
            	escape(m)
510
            ELSE
511
	            IF getShortcut(key) THEN
9187 akron1 512
	            	IF m.parent # NIL THEN
9648 akron1 513
	            		temp := m.parent.tid;
514
	            		m.parent.tid := 0;
9902 akron1 515
	            		G.destroy(m.parent.canvas);
9648 akron1 516
	            		K.ExitID(temp)
517
	            	END;
518
	                exit(m)
519
	            END
8728 leency 520
            END;
521
            repaint(m)
522
        |6:
9208 akron1 523
        	K.mouse(msState, x, y);
9730 akron1 524
        	temp := (x + m.winX)*65536 + (y + m.winY);
525
        	K.SendIPC(m.mainTID, SYSTEM.ADR(temp), SYSTEM.SIZE(INTEGER));
8728 leency 526
            IF (0 <= x) & (x < m.width) & (0 <= y) & (y < m.height) THEN
9174 akron1 527
            	m.active := TRUE;
9671 akron1 528
                m.selItem := (y - TOP) DIV itemHeight;
8728 leency 529
                IF 8 IN msState THEN
9671 akron1 530
                    m.cliItem := (y - TOP) DIV itemHeight
8728 leency 531
                END;
532
                IF 16 IN msState THEN
533
                    IF m.cliItem = m.selItem THEN
534
                        click(m, m.cliItem)
535
                    END;
536
                    m.cliItem := -1
537
                END
538
            ELSE
9174 akron1 539
            	m.active := FALSE;
8728 leency 540
                m.cliItem := -1;
9174 akron1 541
                IF ({8, 9, 10, 16} * msState # {}) & ~isActive(m.child) THEN
8728 leency 542
                    exit(m)
543
                END
544
            END;
9174 akron1 545
            repaint(m);
9187 akron1 546
            IF submenu(m, FALSE) THEN END
8728 leency 547
        END
548
    END
549
END window;
550
 
551
 
9174 akron1 552
PROCEDURE level (m: tMenu): INTEGER;
553
VAR
554
	res: INTEGER;
555
BEGIN
556
	res := 0;
557
	WHILE m.parent # NIL DO
558
		INC(res);
559
		m := m.parent
560
	END
561
	RETURN res
562
END level;
563
 
564
 
565
PROCEDURE open* (m: tMenu; x, y: INTEGER);
566
VAR
567
	L: INTEGER;
568
BEGIN
569
    IF m.tid = 0 THEN
570
        L := level(m);
9448 akron1 571
        IF K.GetThreadSlot(TIDs[L]) = 0 THEN
9187 akron1 572
        	m.winX := x;
573
        	m.winY := y;
9902 akron1 574
        	IF m.canvas = NIL THEN
575
    			m.canvas := G.CreateCanvas(m.width + 1, m.height + 1);
576
			    G.SetFont(m.canvas, m.font)
577
    		END;
9187 akron1 578
	        SYSTEM.PUT(SYSTEM.ADR(stack[L][LEN(stack[0]) - 1]), m);
579
    	    m.tid := K.CreateThread(SYSTEM.ADR(window), stack[L]);
580
        	TIDs[L] := m.tid
581
        END
9174 akron1 582
    END
583
END open;
584
 
585
 
8728 leency 586
PROCEDURE AddMenuItem* (items: List.tList; id: INTEGER; s: ARRAY OF WCHAR);
587
VAR
588
    item: tItem;
589
BEGIN
590
    NEW(item);
591
    item.id := id;
592
    item.text := s;
593
    item.enabled := TRUE;
594
    item.delim := FALSE;
9174 akron1 595
    item.child := NIL;
8728 leency 596
    List.append(items, item);
597
END AddMenuItem;
598
 
599
 
600
PROCEDURE delimiter* (items: List.tList);
601
BEGIN
602
    items.last(tItem).delim := TRUE
603
END delimiter;
604
 
605
 
9174 akron1 606
PROCEDURE child* (items: List.tList; menu: tMenu);
607
BEGIN
608
    items.last(tItem).child := menu
609
END child;
610
 
611
 
8728 leency 612
PROCEDURE getItem (m: tMenu; id: INTEGER): tItem;
613
VAR
614
    item: tItem;
615
BEGIN
616
    item := m.items.first(tItem);
617
    WHILE (item # NIL) & (item.id # id) DO
618
        item := item.next(tItem)
619
    END
620
    RETURN item
621
END getItem;
622
 
623
 
624
PROCEDURE setEnabled* (m: tMenu; id: INTEGER; value: BOOLEAN);
625
VAR
626
    item: tItem;
627
BEGIN
628
    item := getItem(m, id);
629
    IF item # NIL THEN
630
        item.enabled := value
631
    END
632
END setEnabled;
633
 
634
 
9182 akron1 635
PROCEDURE check* (m: tMenu; id: INTEGER; value: BOOLEAN);
8728 leency 636
VAR
637
    item: tItem;
638
BEGIN
639
    item := getItem(m, id);
640
    IF item # NIL THEN
9182 akron1 641
        item.check := ORD(value)
8728 leency 642
    END
9182 akron1 643
END check;
8728 leency 644
 
645
 
9182 akron1 646
PROCEDURE option* (m: tMenu; id: INTEGER; value: BOOLEAN);
647
VAR
648
    item: tItem;
649
BEGIN
650
    item := getItem(m, id);
651
    IF item # NIL THEN
652
        item.check := ORD(value)*2
653
    END
654
END option;
655
 
656
 
8728 leency 657
PROCEDURE isEnabled* (m: tMenu; id: INTEGER): BOOLEAN;
658
VAR
659
    item: tItem;
660
BEGIN
661
    item := getItem(m, id)
662
    RETURN (item # NIL) & item.enabled
663
END isEnabled;
664
 
665
 
9730 akron1 666
PROCEDURE create* (items: List.tList; mainTID: INTEGER): tMenu;
8728 leency 667
VAR
668
    m: tMenu;
669
    maxLength: INTEGER;
670
    item: tItem;
671
BEGIN
672
    NEW(m);
673
    m.tid := 0;
9174 akron1 674
    m.active := FALSE;
675
    m.parent := NIL;
676
    m.child := NIL;
9187 akron1 677
    m.mainID := 0;
9730 akron1 678
    m.mainTID := mainTID;
8728 leency 679
    m.items  := items;
680
    maxLength := 0;
681
    item := items.first(tItem);
682
    WHILE item # NIL DO
683
        maxLength := MAX(maxLength, LENGTH(item.text));
684
        item := item.next(tItem)
685
    END;
686
    m.width  := maxLength*fontWidth + LEFT + RIGHT;
9671 akron1 687
    m.height := items.count*itemHeight - 2;
688
    m.font := G.fonts[1];
9902 akron1 689
(*    m.canvas := G.CreateCanvas(m.width + 1, m.height + 1);
690
    G.SetFont(m.canvas, m.font)*)
8728 leency 691
    RETURN m
692
END create;
693
 
9174 akron1 694
 
9648 akron1 695
PROCEDURE AddShortcut* (key, MenuItem: INTEGER);
696
VAR
697
	item: tShortcut;
698
BEGIN
699
	NEW(item);
700
	item.key := key;
701
	item.MenuItem := MenuItem;
702
	List.append(shortcuts, item)
703
END AddShortcut;
704
 
705
 
9174 akron1 706
PROCEDURE init* (_resetTimer: tProc);
707
VAR
708
	i: INTEGER;
709
BEGIN
9648 akron1 710
	SetItem(0);
711
	shortcuts := List.create(NIL);
9174 akron1 712
	resetTimer := _resetTimer;
713
	_open := open;
714
	FOR i := 0 TO maxLEVEL DO
715
		TIDs[i] := 0
716
	END
717
END init;
718
 
719
 
8728 leency 720
END Menu.