Subversion Repositories Kolibri OS

Rev

Rev 9187 | Rev 9208 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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