Subversion Repositories Kolibri OS

Rev

Rev 9182 | Rev 9190 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 9182 Rev 9187
Line 18... Line 18...
18
*)
18
*)
Line 19... Line 19...
19
 
19
 
Line 20... Line 20...
20
MODULE Menu;
20
MODULE Menu;
21
 
21
 
Line 22... Line 22...
22
IMPORT
22
IMPORT
23
    SYSTEM, G := Graph, List, K := KolibriOS;
23
    SYSTEM, G := Graph, List, K := KolibriOS, U := Utils, KOSAPI;
24
 
24
 
Line -... Line 25...
-
 
25
CONST
-
 
26
    fontHeight = 22;
25
CONST
27
    fontWidth = 8;
26
    fontHeight = 22;
28
 
27
    fontWidth = 8;
29
    MainMenuHeight* = K.fontHeight + 7;
Line 28... Line 30...
28
 
30
 
Line 42... Line 44...
42
    disSelForeColor = disForeColor;
44
    disSelForeColor = disForeColor;
Line 43... Line 45...
43
 
45
 
Line -... Line 46...
-
 
46
 
-
 
47
TYPE
-
 
48
 
-
 
49
	tMainItem* = POINTER TO descMainItem;
-
 
50
 
-
 
51
    tMain* = POINTER TO RECORD (List.tList)
44
 
52
    	id: INTEGER
45
TYPE
53
    END;
46
 
54
 
47
    tMenu* = POINTER TO RECORD
55
    tMenu* = POINTER TO RECORD
-
 
56
        tid*: INTEGER;
48
        tid*: INTEGER;
57
        active*, keyboard: BOOLEAN;
49
        active*: BOOLEAN;
58
        parent*, child: tMenu;
Line 50... Line 59...
50
        parent*, child: tMenu;
59
        mainID: INTEGER;
51
        winX, winY, width*, height*: INTEGER;
60
        winX, winY, width*, height*: INTEGER;
Line 64... Line 73...
64
        text: ARRAY 32 OF WCHAR;
73
        text: ARRAY 32 OF WCHAR;
65
        enabled, delim: BOOLEAN;
74
        enabled, delim: BOOLEAN;
66
        child: tMenu
75
        child: tMenu
67
    END;
76
    END;
Line -... Line 77...
-
 
77
 
-
 
78
    descMainItem = RECORD (List.tItem)
-
 
79
        id*, x: INTEGER;
-
 
80
        text: ARRAY 32 OF WCHAR;
-
 
81
        menu*: tMenu;
-
 
82
        main: tMain
-
 
83
    END;
68
 
84
 
69
    tClick = PROCEDURE (menu: tMenu; id: INTEGER);
85
    tClick = PROCEDURE (menu: tMenu; id: INTEGER);
70
    tKey = PROCEDURE (menu: tMenu; key: INTEGER): BOOLEAN;
86
    tKey = PROCEDURE (menu: tMenu; key: INTEGER): BOOLEAN;
Line 71... Line 87...
71
    tProc = PROCEDURE;
87
    tProc = PROCEDURE;
72
 
88
 
73
VAR
89
VAR
74
    stack: ARRAY maxLEVEL + 1, 250000 OF INTEGER;
90
    stack: ARRAY maxLEVEL + 1, 250000 OF INTEGER;
75
    TIDs: ARRAY maxLEVEL + 1 OF INTEGER;
91
    TIDs: ARRAY maxLEVEL + 1 OF INTEGER;
76
    resetTimer: tProc;
92
    resetTimer: tProc;
77
    _open: PROCEDURE (m: tMenu; x, y: INTEGER);
93
    _open: PROCEDURE (m: tMenu; x, y: INTEGER);
78
    redraw*: BOOLEAN;
94
    (*redraw*: BOOLEAN;*)
79
(*
95
(*
80
    backColor, foreColor, selBackColor, selForeColor,
96
    backColor, foreColor, selBackColor, selForeColor,
Line -... Line 97...
-
 
97
    disBackColor, disForeColor, disSelBackColor, disSelForeColor: INTEGER;
-
 
98
*)
-
 
99
 
-
 
100
PROCEDURE AddMainItem* (main: tMain; text: ARRAY OF WCHAR; menu: tMenu);
-
 
101
VAR
-
 
102
	item, prev: tMainItem;
-
 
103
BEGIN
-
 
104
	NEW(item);
-
 
105
	item.id := main.id + main.count;
-
 
106
	COPY(text, item.text);
-
 
107
	item.menu := menu;
-
 
108
	item.main := main;
-
 
109
	menu.mainID := item.id;
-
 
110
	List.append(main, item);
-
 
111
	prev := item.prev(tMainItem);
-
 
112
	IF prev # NIL THEN
-
 
113
		item.x := prev.x + LENGTH(prev.text)*fontWidth + 9
-
 
114
	ELSE
-
 
115
		item.x := 0
-
 
116
	END
-
 
117
END AddMainItem;
-
 
118
 
-
 
119
 
-
 
120
PROCEDURE CreateMain* (id: INTEGER): tMain;
-
 
121
VAR
-
 
122
	res: tMain;
-
 
123
	list: List.tList;
-
 
124
BEGIN
-
 
125
	NEW(res);
-
 
126
	res.id := id;
-
 
127
	list := List.create(res)
-
 
128
	RETURN res
-
 
129
END CreateMain;
-
 
130
 
-
 
131
 
-
 
132
PROCEDURE drawMainItem (item: tMainItem);
-
 
133
VAR
-
 
134
    menuColor, textColor, n: INTEGER;
-
 
135
BEGIN
-
 
136
    IF item.menu.tid # 0 THEN
-
 
137
        menuColor := K.textColor;
-
 
138
        textColor := K.winColor
-
 
139
    ELSE
-
 
140
        menuColor := K.winColor;
-
 
141
        textColor := K.textColor
-
 
142
    END;
-
 
143
    n := LENGTH(item.text);
-
 
144
    K.DrawRect(item.x, 0, n*fontWidth + 2, MainMenuHeight, menuColor);
-
 
145
    K.CreateButton(item.id + ORD({30}), item.x, 0, n*fontWidth + 2, MainMenuHeight, K.btnColor, "");
-
 
146
    K.DrawText(item.x + 1, (MainMenuHeight - K.fontHeight) DIV 2 + 1, textColor, item.text)
-
 
147
END drawMainItem;
-
 
148
 
-
 
149
 
-
 
150
PROCEDURE DrawMain* (main: tMain);
-
 
151
VAR
-
 
152
	item: List.tItem;
-
 
153
BEGIN
-
 
154
	item := main.first;
-
 
155
	WHILE item # NIL DO
-
 
156
		drawMainItem(item(tMainItem));
-
 
157
		item := item.next
-
 
158
	END
-
 
159
END DrawMain;
-
 
160
 
-
 
161
 
-
 
162
PROCEDURE getMainID (m: tMenu): INTEGER;
-
 
163
BEGIN
-
 
164
	WHILE m.parent # NIL DO
-
 
165
		m := m.parent
-
 
166
	END
-
 
167
	RETURN m.mainID
-
 
168
END getMainID;
-
 
169
 
-
 
170
 
-
 
171
PROCEDURE ClickMain* (main: tMain; btn: INTEGER): tMenu;
-
 
172
VAR
-
 
173
	item: List.tItem;
-
 
174
	res: tMenu;
-
 
175
BEGIN
-
 
176
	item := List.getItem(main, btn - main.id);
-
 
177
	IF item # NIL THEN
-
 
178
		res := item(tMainItem).menu
-
 
179
	ELSE
-
 
180
		res := NIL
-
 
181
	END
-
 
182
	RETURN res
81
    disBackColor, disForeColor, disSelBackColor, disSelForeColor: INTEGER;
183
END ClickMain;
82
*)
184
 
83
 
185
 
84
PROCEDURE isSender* (tid: INTEGER): BOOLEAN;
186
PROCEDURE isSender* (tid: INTEGER): BOOLEAN;
85
VAR
187
VAR
Line 93... Line 195...
93
END isSender;
195
END isSender;
Line 94... Line 196...
94
 
196
 
95
 
197
 
96
PROCEDURE exit (m: tMenu);
-
 
97
BEGIN
198
PROCEDURE exit (m: tMenu);
98
    m.tid := 0;
199
BEGIN
-
 
200
    m.active := FALSE;
99
    m.active := FALSE;
201
   	resetTimer;
100
    resetTimer;
202
    m.tid := 0;
Line -... Line 203...
-
 
203
    K.Exit
-
 
204
END exit;
-
 
205
 
-
 
206
 
-
 
207
PROCEDURE escape (m: tMenu);
-
 
208
BEGIN
-
 
209
    m.active := FALSE;
-
 
210
    IF m.parent = NIL THEN
-
 
211
    	resetTimer
-
 
212
    END;
-
 
213
    m.tid := 0;
101
    K.Exit
214
    K.Exit
102
END exit;
215
END escape;
103
 
216
 
104
 
217
 
105
PROCEDURE repaint (m: tMenu);
218
PROCEDURE repaint (m: tMenu);
Line 200... Line 313...
200
    y := mouseY - m.winY;
313
    y := mouseY - m.winY;
201
END mouse;
314
END mouse;
Line 202... Line 315...
202
 
315
 
-
 
316
 
-
 
317
PROCEDURE close* (m: tMenu);
203
 
318
VAR
204
PROCEDURE close* (m: tMenu);
319
	temp: INTEGER;
205
BEGIN
320
BEGIN
206
    IF (m # NIL) & (m.tid # 0) THEN
321
    IF (m # NIL) & (m.tid # 0) THEN
207
    	IF m.child # NIL THEN
322
    	IF m.child # NIL THEN
208
    		close(m.child);
323
    		close(m.child);
209
    		m.child := NIL
324
    		m.child := NIL
210
    	END;
325
    	END;
-
 
326
    	temp := m.tid;
211
        K.ExitID(m.tid);
327
    	m.tid := 0;
212
        m.tid := 0;
328
        K.ExitID(temp);
213
        m.active := FALSE
329
        m.active := FALSE
Line 214... Line 330...
214
    END
330
    END
215
END close;
331
END close;
216
 
332
 
217
 
333
 
-
 
334
PROCEDURE click (m: tMenu; i: INTEGER);
218
PROCEDURE click (m: tMenu; i: INTEGER);
335
VAR
-
 
336
    item: List.tItem;
-
 
337
    p: tMenu;
-
 
338
    id: INTEGER;
-
 
339
BEGIN
219
VAR
340
	id := -1;
220
    item: List.tItem;
341
	IF i < 0 THEN
221
    p: tMenu;
342
		id := i
-
 
343
	ELSE
-
 
344
	    item := List.getItem(m.items, i);
-
 
345
	    IF (item # NIL) & item(tItem).enabled & (item(tItem).child = NIL) THEN
-
 
346
	    	id := item(tItem).id
222
BEGIN
347
	    END
223
    item := List.getItem(m.items, i);
348
    END;
224
    IF (item # NIL) & item(tItem).enabled & (item(tItem).child = NIL) THEN
349
    IF id # -1 THEN
225
        m.click(m, item(tItem).id);
350
	    m.click(m, id);
226
        p := m.parent;
351
	    p := m.parent;
227
       	WHILE p # NIL DO
352
	   	WHILE p # NIL DO
228
       		p.child := NIL;
353
	   		p.child := NIL;
229
       		close(p);
354
	   		close(p);
230
       		p := p.parent
355
	   		p := p.parent
231
       	END;
356
	   	END;
Line 246... Line 371...
246
 
371
 
247
 
372
 
248
PROCEDURE closeChild (m: tMenu);
373
PROCEDURE closeChild (m: tMenu);
249
BEGIN
374
BEGIN
250
	IF m.child # NIL THEN
375
	IF m.child # NIL THEN
251
		redraw := FALSE;
376
		(*redraw := FALSE;*)
252
		close(m.child);
377
		close(m.child);
253
		m.child := NIL
378
		m.child := NIL
Line 254... Line 379...
254
	END
379
	END
255
END closeChild;
380
END closeChild;
256
 
381
 
-
 
382
 
257
 
383
PROCEDURE submenu (m: tMenu; keyboard: BOOLEAN): BOOLEAN;
-
 
384
VAR
258
PROCEDURE submenu (m: tMenu);
385
	item: List.tItem;
259
VAR
386
	res: BOOLEAN;
-
 
387
BEGIN
260
	item: List.tItem;
388
	res := FALSE;
261
BEGIN
389
    item := List.getItem(m.items, m.selItem);
-
 
390
    IF (item # NIL) & item(tItem).enabled & (item(tItem).child # NIL) THEN
262
    item := List.getItem(m.items, m.selItem);
391
    	res := TRUE;
263
    IF (item # NIL) & item(tItem).enabled & (item(tItem).child # NIL) THEN
392
    	IF ~opened(item(tItem).child) THEN
264
    	IF ~opened(item(tItem).child) THEN
393
    		closeChild(m);
265
    		closeChild(m);
394
    		item(tItem).child.keyboard := keyboard;
266
    		_open(item(tItem).child, m.winX + m.width - 2, m.winY + m.selItem*fontHeight);
395
    		_open(item(tItem).child, m.winX + m.width - 2, m.winY + m.selItem*fontHeight);
267
    		m.child := item(tItem).child
396
    		m.child := item(tItem).child;
-
 
397
    	END
268
    	END
398
    ELSE
Line 269... Line 399...
269
    ELSE
399
    	closeChild(m)
270
    	closeChild(m)
400
    END
271
    END
401
    RETURN res
272
END submenu;
402
END submenu;
273
 
403
 
-
 
404
 
274
 
405
PROCEDURE [stdcall] window (m: tMenu);
275
PROCEDURE [stdcall] window (m: tMenu);
406
VAR
276
VAR
407
    x, y: INTEGER;
-
 
408
    key, temp: INTEGER;
277
    x, y: INTEGER;
409
    msState: SET;
278
    key: INTEGER;
410
    shift, ctrl: BOOLEAN;
279
    msState: SET;
411
BEGIN
280
BEGIN
412
    m.selItem := ORD(m.keyboard) - 1;
281
    m.selItem := -1;
413
    m.cliItem := -1;
282
    m.cliItem := -1;
414
    m.keyboard := FALSE;
-
 
415
    K.SetEventsMask({0, 1, 5});
283
    K.SetEventsMask({0, 1, 5});
416
    WHILE TRUE DO
-
 
417
        CASE K.WaitForEvent() OF
284
    WHILE TRUE DO
418
        |1:
285
        CASE K.WaitForEvent() OF
419
            draw_window(m)
286
        |1:
420
        |2:
287
            draw_window(m)
421
        	K.getKBState(shift, ctrl);
288
        |2:
422
            key := K.GetKey();
289
            key := K.GetKey();
423
            IF ~shift & ~ ctrl THEN
290
            IF key DIV 65536 = 72 THEN
424
	            IF key DIV 65536 = 72 THEN
291
                DEC(m.selItem);
425
	                DEC(m.selItem);
292
                IF m.selItem < 0 THEN
426
	                IF m.selItem < 0 THEN
293
                    m.selItem := 0
427
	                    m.selItem := m.items.count - 1
294
                END
428
	                END
295
            ELSIF key DIV 65536 = 80 THEN
429
	            ELSIF key DIV 65536 = 80 THEN
296
                INC(m.selItem);
430
	                INC(m.selItem);
297
                IF m.selItem >= m.items.count THEN
431
	                IF m.selItem >= m.items.count THEN
298
                    m.selItem := m.items.count - 1
432
	                    m.selItem := 0
299
                END
433
	                END
-
 
434
	            ELSIF key DIV 65536 = 28 THEN
-
 
435
	                IF m.selItem >= 0 THEN
300
            ELSIF key DIV 65536 = 28 THEN
436
	                    click(m, m.selItem)
-
 
437
	                END;
301
                IF m.selItem >= 0 THEN
438
	                m.cliItem := -1
302
                    click(m, m.selItem)
439
	            ELSIF key DIV 65536 = 77 THEN
-
 
440
	                IF ~submenu(m, TRUE) THEN
-
 
441
	                	click(m, -(getMainID(m) + 1))
-
 
442
	                END;
-
 
443
	                m.cliItem := -1
-
 
444
	            ELSIF key DIV 65536 = 75 THEN
-
 
445
	            	IF m.parent # NIL THEN
-
 
446
	                	escape(m)
-
 
447
	            	ELSE
-
 
448
	            		click(m, -(getMainID(m) - 1))
-
 
449
	                END;
-
 
450
	                m.cliItem := -1
-
 
451
	            ELSIF key DIV 65536 = 1 THEN
-
 
452
	            	escape(m)
-
 
453
	            ELSE
303
                END;
454
	                IF m.key(m, key) THEN
304
                m.cliItem := -1
455
	                	IF m.parent # NIL THEN
-
 
456
	                		temp := m.parent.tid;
305
            ELSIF key DIV 65536 = 77 THEN
457
	                		m.parent.tid := 0;
306
                submenu(m)
458
	                		K.ExitID(temp)
-
 
459
	                	END;
-
 
460
	                    exit(m)
-
 
461
	                END
-
 
462
                END
-
 
463
            ELSE
307
            ELSIF key DIV 65536 = 75 THEN
464
                IF m.key(m, key) THEN
308
            	IF m.parent # NIL THEN
465
                	IF m.parent # NIL THEN
309
                	exit(m)
466
                		temp := m.parent.tid;
310
                END
467
                		m.parent.tid := 0;
311
            ELSE
468
                		K.ExitID(temp)
Line 335... Line 492...
335
                IF ({8, 9, 10, 16} * msState # {}) & ~isActive(m.child) THEN
492
                IF ({8, 9, 10, 16} * msState # {}) & ~isActive(m.child) THEN
336
                    exit(m)
493
                    exit(m)
337
                END
494
                END
338
            END;
495
            END;
339
            repaint(m);
496
            repaint(m);
340
            submenu(m)
497
            IF submenu(m, FALSE) THEN END
341
        END
498
        END
342
    END
499
    END
343
END window;
500
END window;
Line 359... Line 516...
359
PROCEDURE open* (m: tMenu; x, y: INTEGER);
516
PROCEDURE open* (m: tMenu; x, y: INTEGER);
360
VAR
517
VAR
361
	L: INTEGER;
518
	L: INTEGER;
362
BEGIN
519
BEGIN
363
    IF m.tid = 0 THEN
520
    IF m.tid = 0 THEN
-
 
521
        L := level(m);
-
 
522
        IF KOSAPI.sysfunc3(18, 21, TIDs[L]) = 0 THEN
364
        m.winX := x;
523
        	m.winX := x;
365
        m.winY := y;
524
        	m.winY := y;
366
        L := level(m);
-
 
367
        SYSTEM.PUT(SYSTEM.ADR(stack[L][LEN(stack[0]) - 1]), m);
525
	        SYSTEM.PUT(SYSTEM.ADR(stack[L][LEN(stack[0]) - 1]), m);
368
        m.tid := K.CreateThread(SYSTEM.ADR(window), stack[L]);
526
    	    m.tid := K.CreateThread(SYSTEM.ADR(window), stack[L]);
369
        TIDs[L] := m.tid
527
        	TIDs[L] := m.tid
370
    END
528
        END
-
 
529
    END
371
END open;
530
END open;
Line 372... Line 531...
372
 
531
 
373
 
532
 
Line 460... Line 619...
460
    NEW(m);
619
    NEW(m);
461
    m.tid := 0;
620
    m.tid := 0;
462
    m.active := FALSE;
621
    m.active := FALSE;
463
    m.parent := NIL;
622
    m.parent := NIL;
464
    m.child := NIL;
623
    m.child := NIL;
-
 
624
    m.mainID := 0;
465
    m.items  := items;
625
    m.items  := items;
466
    m.click := click;
626
    m.click := click;
467
    m.key := key;
627
    m.key := key;
468
    maxLength := 0;
628
    maxLength := 0;
469
    item := items.first(tItem);
629
    item := items.first(tItem);
Line 477... Line 637...
477
    m.canvas := G.CreateCanvas(m.width + 1, m.height + 1);
637
    m.canvas := G.CreateCanvas(m.width + 1, m.height + 1);
478
    G.SetFont(m.canvas, m.font);
638
    G.SetFont(m.canvas, m.font);
479
    RETURN m
639
    RETURN m
480
END create;
640
END create;
Line 481... Line 641...
481
 
641
 
482
 
642
(*
483
PROCEDURE Redraw*;
643
PROCEDURE Redraw*;
484
BEGIN
644
BEGIN
485
	redraw := TRUE
645
	redraw := TRUE
486
END Redraw;
646
END Redraw;
Line 487... Line 647...
487
 
647
*)
488
 
648
 
489
PROCEDURE init* (_resetTimer: tProc);
649
PROCEDURE init* (_resetTimer: tProc);
490
VAR
650
VAR
491
	i: INTEGER;
651
	i: INTEGER;
492
BEGIN
652
BEGIN
493
	Redraw;
653
	(*Redraw;*)
494
	resetTimer := _resetTimer;
654
	resetTimer := _resetTimer;
495
	_open := open;
655
	_open := open;
496
	FOR i := 0 TO maxLEVEL DO
656
	FOR i := 0 TO maxLEVEL DO