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 |