1 /* NetHack 3.6 winmenu.c $NHDT-Date: 1432512796 2015/05/25 00:13:16 $ $NHDT-Branch: master $:$NHDT-Revision: 1.7 $ */
2 /* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1991,1992,1993,1996.
4 /* NetHack may be freely redistributed. See license for details. */
6 #include "NH:sys/amiga/windefs.h"
7 #include "NH:sys/amiga/winext.h"
8 #include "NH:sys/amiga/winproto.h"
10 /* Start building the text for a menu */
12 amii_start_menu(window
)
13 register winid window
;
16 register struct amii_WinDesc
*cw
;
17 register amii_menu_item
*mip
;
19 if (window
== WIN_ERR
|| (cw
= amii_wins
[window
]) == NULL
20 || cw
->type
!= NHW_MENU
)
21 panic(winpanicstr
, window
, "start_menu");
23 amii_clear_nhwindow(window
);
25 if (cw
->data
&& (cw
->type
== NHW_MESSAGE
|| cw
->type
== NHW_MENU
26 || cw
->type
== NHW_TEXT
)) {
27 for (i
= 0; i
< cw
->maxrow
; ++i
) {
35 for (mip
= cw
->menu
.items
, i
= 0;
36 (mip
= cw
->menu
.items
) && i
< cw
->menu
.count
; ++i
) {
37 cw
->menu
.items
= mip
->next
;
49 if (window
== WIN_INVEN
&& cw
->win
!= NULL
) {
53 cw
->cury
= cw
->rows
= cw
->maxrow
= cw
->maxcol
= 0;
57 /* Add a string to a menu */
59 amii_add_menu(window
, glyph
, id
, ch
, gch
, attr
, str
, preselected
)
60 register winid window
;
62 register const anything
*id
;
66 register const char *str
;
67 register BOOLEAN_P preselected
;
69 register struct amii_WinDesc
*cw
;
76 if (window
== WIN_ERR
|| (cw
= amii_wins
[window
]) == NULL
77 || cw
->type
!= NHW_MENU
)
78 panic(winpanicstr
, window
, "add_menu");
80 mip
= (amii_menu_item
*) alloc(sizeof(*mip
));
81 mip
->identifier
= *id
;
82 mip
->selected
= preselected
;
84 mip
->glyph
= Is_rogue_level(&u
.uz
) ? NO_GLYPH
: glyph
;
89 if (id
->a_void
&& !ch
&& cw
->menu
.chr
!= 0) {
97 mip
->canselect
= (id
->a_void
!= 0);
99 if (id
->a_void
&& ch
!= '\0') {
100 Sprintf(buf
, "%c - %s", ch
, str
);
107 amii_putstr(window
, attr
, str
);
109 mip
->str
= cw
->data
[cw
->cury
- 1];
114 if (cw
->menu
.items
== 0)
115 cw
->menu
.last
= cw
->menu
.items
= mip
;
117 cw
->menu
.last
->next
= mip
;
122 /* Done building a menu. */
125 amii_end_menu(window
, morestr
)
126 register winid window
;
127 register const char *morestr
;
129 register struct amii_WinDesc
*cw
;
131 if (window
== WIN_ERR
|| (cw
= amii_wins
[window
]) == NULL
132 || cw
->type
!= NHW_MENU
)
133 panic(winpanicstr
, window
, "end_menu");
135 if (morestr
&& *morestr
) {
137 #define PROMPTFIRST /* Define this to have prompt first */
145 amii_add_menu(window
, NO_GLYPH
, &any
, 0, 0, ATR_NONE
, morestr
,
147 #ifdef PROMPTFIRST /* Do some shuffling. Last first, push others one forward \
150 cw
->menu
.last
->next
= cw
->menu
.items
;
151 cw
->menu
.items
= cw
->menu
.last
;
153 t
= cw
->data
[cw
->cury
- 1];
154 for (i
= cw
->cury
- 1; i
> 0; i
--) {
155 cw
->data
[i
] = cw
->data
[i
- 1];
161 /* If prompt first, don't put same string in title where in most cases
162 it's not entirely visible anyway */
165 cw
->morestr
= strdup(morestr
);
169 /* Select something from the menu. */
172 amii_select_menu(window
, how
, mip
)
173 register winid window
;
175 register menu_item
**mip
;
178 register struct amii_WinDesc
*cw
;
180 if (window
== WIN_ERR
|| (cw
= amii_wins
[window
]) == NULL
181 || cw
->type
!= NHW_MENU
)
182 panic(winpanicstr
, window
, "select_menu");
184 cnt
= DoMenuScroll(window
, 1, how
, mip
);
186 /* This would allow the inventory window to stay open. */
187 if (!alwaysinvent
|| window
!= WIN_INVEN
)
188 dismiss_nhwindow(window
); /* Now tear it down */
193 find_menu_item(register struct amii_WinDesc
*cw
, int idx
)
196 for (mip
= cw
->menu
.items
; idx
> 0 && mip
; mip
= mip
->next
)
203 make_menu_items(register struct amii_WinDesc
*cw
, register menu_item
**rmip
)
205 register int idx
= 0;
206 register amii_menu_item
*mip
;
207 register menu_item
*mmip
;
209 for (mip
= cw
->menu
.items
; mip
; mip
= mip
->next
) {
215 mmip
= *rmip
= (menu_item
*) alloc(idx
* sizeof(*mip
));
216 for (mip
= cw
->menu
.items
; mip
; mip
= mip
->next
) {
218 mmip
->item
= mip
->identifier
;
219 mmip
->count
= mip
->count
;
230 DoMenuScroll(win
, blocking
, how
, retmip
)
231 int win
, blocking
, how
;
234 amii_menu_item
*amip
;
235 register struct Window
*w
;
236 register struct NewWindow
*nw
;
237 struct PropInfo
*pip
;
238 register struct amii_WinDesc
*cw
;
239 struct IntuiMessage
*imsg
;
241 register int wheight
, xsize
, ysize
, aredone
= 0;
242 register int txwd
, txh
;
243 long mics
, secs
, class, code
;
244 long oldmics
= 0, oldsecs
= 0;
245 int aidx
, oidx
, topidx
, hidden
;
248 static char title
[100];
250 struct Screen
*scrn
= HackScreen
;
252 long counting
= FALSE
, count
= 0, reset_counting
= FALSE
;
253 char countString
[32];
255 if (win
== WIN_ERR
|| (cw
= amii_wins
[win
]) == NULL
)
256 panic(winpanicstr
, win
, "DoMenuScroll");
258 /* Initial guess at window sizing values */
261 if (win
== WIN_INVEN
)
262 txh
= max(txheight
, pictdata
.ysize
+ 3); /* interline space */
264 txh
= txheight
; /* interline space */
266 txh
= txheight
; /* interline space */
268 /* Check to see if we should open the window, should need to for
269 * TEXT and MENU but not MESSAGE.
276 #ifdef INTUI_NEW_LOOK
277 if (IntuitionBase
->LibNode
.lib_Version
>= 37) {
278 PropScroll
.Flags
|= PROPNEWLOOK
;
281 nw
= (void *) DupNewWindow((void *) (&new_wins
[cw
->type
].newwin
));
282 if (!alwaysinvent
|| win
!= WIN_INVEN
) {
283 xsize
= scrn
->WBorLeft
+ scrn
->WBorRight
+ MenuScroll
.Width
+ 1
284 + (txwd
* cw
->maxcol
);
286 if (win
== WIN_INVEN
)
287 xsize
+= pictdata
.xsize
+ 4;
289 if (xsize
> amiIDisplay
->xpix
)
290 xsize
= amiIDisplay
->xpix
;
292 /* If next row not off window, use it, else use the bottom */
294 ysize
= (txh
* cw
->maxrow
) + /* The text space */
295 HackScreen
->WBorTop
+ txheight
+ 1 + /* Top border */
296 HackScreen
->WBorBottom
+ 3; /* The bottom border */
297 if (ysize
> amiIDisplay
->ypix
)
298 ysize
= amiIDisplay
->ypix
;
300 /* Adjust the size of the menu scroll gadget */
303 if (cw
->type
== NHW_TEXT
&& ysize
< amiIDisplay
->ypix
)
304 nw
->TopEdge
+= (amiIDisplay
->ypix
- ysize
) / 2;
305 nw
->LeftEdge
= amiIDisplay
->xpix
- xsize
;
306 if (cw
->type
== NHW_MENU
) {
307 if (nw
->LeftEdge
> 10)
311 if (amiIDisplay
->ypix
- nw
->Height
> 10)
314 nw
->TopEdge
= amiIDisplay
->ypix
- nw
->Height
- 1;
316 if (cw
->type
== NHW_TEXT
&& xsize
< amiIDisplay
->xpix
)
317 nw
->LeftEdge
-= (amiIDisplay
->xpix
- xsize
) / 2;
318 } else if (win
== WIN_INVEN
) {
319 struct Window
*mw
= amii_wins
[WIN_MAP
]->win
;
320 struct Window
*sw
= amii_wins
[WIN_STATUS
]->win
;
322 xsize
= scrn
->WBorLeft
+ scrn
->WBorRight
+ MenuScroll
.Width
+ 1
323 + (txwd
* cw
->maxcol
);
325 /* Make space for the glyph to appear at the left of the
328 xsize
+= pictdata
.xsize
+ 4;
330 if (xsize
> amiIDisplay
->xpix
)
331 xsize
= amiIDisplay
->xpix
;
333 /* If next row not off window, use it, else use the bottom */
335 ysize
= sw
->TopEdge
- (mw
->TopEdge
+ mw
->Height
) - 1;
336 if (ysize
> amiIDisplay
->ypix
)
337 ysize
= amiIDisplay
->ypix
;
339 /* Adjust the size of the menu scroll gadget */
341 nw
->TopEdge
= mw
->TopEdge
+ mw
->Height
;
344 cw
->newwin
= (void *) nw
;
346 panic("No NewWindow Allocated");
348 nw
->Screen
= HackScreen
;
350 if (win
== WIN_INVEN
) {
351 sprintf(title
, "%s the %s's Inventory", plname
, pl_character
);
353 if (lastinvent
.MaxX
!= 0) {
354 nw
->LeftEdge
= lastinvent
.MinX
;
355 nw
->TopEdge
= lastinvent
.MinY
;
356 nw
->Width
= lastinvent
.MaxX
;
357 nw
->Height
= lastinvent
.MaxY
;
359 } else if (cw
->morestr
)
360 nw
->Title
= cw
->morestr
;
362 /* Adjust the window coordinates and size now that we know
363 * how many items are to be displayed.
366 if ((xsize
> amiIDisplay
->xpix
- nw
->LeftEdge
)
367 && (xsize
< amiIDisplay
->xpix
)) {
368 nw
->LeftEdge
= amiIDisplay
->xpix
- xsize
;
371 nw
->Width
= min(xsize
, amiIDisplay
->xpix
- nw
->LeftEdge
);
373 nw
->Height
= min(ysize
, amiIDisplay
->ypix
- nw
->TopEdge
);
375 if (WINVERS_AMIV
|| WINVERS_AMII
) {
376 /* Make sure we are using the correct hook structure */
377 nw
->Extension
= cw
->wintags
;
380 /* Now, open the window */
381 w
= cw
->win
= OpenShWindow((void *) nw
);
386 sprintf(buf
, "No Window Opened For Menu (%d,%d,%d-%d,%d-%d)",
387 nw
->LeftEdge
, nw
->TopEdge
, nw
->Width
, amiIDisplay
->xpix
,
388 nw
->Height
, amiIDisplay
->ypix
);
394 SetFont(w
->RPort
, TextsFont
);
396 SetFont(w
->RPort
, HackFont
);
398 txwd
= w
->RPort
->TxWidth
;
400 if (win
== WIN_INVEN
)
401 txh
= max(w
->RPort
->TxHeight
,
402 pictdata
.ysize
+ 3); /* interline space */
404 txh
= w
->RPort
->TxHeight
; /* interline space */
406 txh
= w
->RPort
->TxHeight
; /* interline space */
408 /* subtract 2 to account for spacing away from border (1 on each side)
410 wheight
= (w
->Height
- w
->BorderTop
- w
->BorderBottom
- 2) / txh
;
412 if (win
== WIN_INVEN
) {
413 cw
->cols
= (w
->Width
- w
->BorderLeft
- w
->BorderRight
- 4
414 - pictdata
.xsize
- 3) / txwd
;
417 (w
->Width
- w
->BorderLeft
- w
->BorderRight
- 4) / txwd
;
420 cw
->cols
= (w
->Width
- w
->BorderLeft
- w
->BorderRight
- 4) / txwd
;
422 totalvis
= CountLines(win
);
424 txwd
= w
->RPort
->TxWidth
;
426 if (win
== WIN_INVEN
)
427 txh
= max(w
->RPort
->TxHeight
,
428 pictdata
.ysize
+ 3); /* interline space */
430 txh
= w
->RPort
->TxHeight
; /* interline space */
432 txh
= w
->RPort
->TxHeight
; /* interline space */
435 /* subtract 2 to account for spacing away from border (1 on each side)
437 wheight
= (w
->Height
- w
->BorderTop
- w
->BorderBottom
- 2) / txh
;
439 if (win
== WIN_INVEN
) {
440 cw
->cols
= (w
->Width
- w
->BorderLeft
- w
->BorderRight
- 4
441 - pictdata
.xsize
- 3) / txwd
;
444 (w
->Width
- w
->BorderLeft
- w
->BorderRight
- 4) / txwd
;
446 cw
->cols
= (w
->Width
- w
->BorderLeft
- w
->BorderRight
- 4) / txwd
;
449 totalvis
= CountLines(win
);
451 for (gd
= w
->FirstGadget
; gd
&& gd
->GadgetID
!= 1;)
455 pip
= (struct PropInfo
*) gd
->SpecialInfo
;
456 hidden
= max(totalvis
- wheight
, 0);
457 topidx
= (((ULONG
) hidden
* pip
->VertPot
) + (MAXPOT
/ 2)) >> 16;
461 for (gd
= w
->FirstGadget
; gd
&& gd
->GadgetID
!= 1;)
465 panic("Can't find scroll gadget");
471 /* Make sure there are no selections left over from last time. */
472 /* XXX potential problem for preselection if this is really needed */
473 for( amip
= cw
->menu
.items
; amip
; amip
= amip
->next
)
477 DisplayData(win
, topidx
);
479 /* Make the prop gadget the right size and place */
481 SetPropInfo(w
, gd
, wheight
, totalvis
, topidx
);
482 oldsecs
= oldmics
= 0;
484 /* If window already up, don't stop to process events */
491 /* Process window messages */
493 WaitPort(w
->UserPort
);
494 while (imsg
= (struct IntuiMessage
*) GetMsg(w
->UserPort
)) {
498 secs
= imsg
->Seconds
;
499 gd
= (struct Gadget
*) imsg
->IAddress
;
503 /* Only do our window or VANILLAKEY from other windows */
505 if (imsg
->IDCMPWindow
!= w
&& class != VANILLAKEY
506 && class != RAWKEY
) {
507 ReplyMsg((struct Message
*) imsg
);
511 /* Do DeadKeyConvert() stuff if RAWKEY... */
512 if (class == RAWKEY
) {
514 code
= ConvertKey(imsg
);
516 ReplyMsg((struct Message
*) imsg
);
522 * Ignore every other newsize, no action needed,
523 * except RefreshWindowFrame() in case borders got overwritten
524 * for some reason. It should not happen, but ...
528 RefreshWindowFrame(w
);
533 if (win
== WIN_INVEN
) {
534 lastinvent
.MinX
= w
->LeftEdge
;
535 lastinvent
.MinY
= w
->TopEdge
;
536 lastinvent
.MaxX
= w
->Width
;
537 lastinvent
.MaxY
= w
->Height
;
538 } else if (win
== WIN_MESSAGE
) {
539 lastmsg
.MinX
= w
->LeftEdge
;
540 lastmsg
.MinY
= w
->TopEdge
;
541 lastmsg
.MaxX
= w
->Width
;
542 lastmsg
.MaxY
= w
->Height
;
545 /* Find the gadget */
547 for (gd
= w
->FirstGadget
; gd
&& gd
->GadgetID
!= 1;)
551 panic("Can't find scroll gadget");
553 totalvis
= CountLines(win
);
555 (w
->Height
- w
->BorderTop
- w
->BorderBottom
- 2) / txh
;
557 if (win
== WIN_INVEN
) {
558 cw
->cols
= (w
->Width
- w
->BorderLeft
- w
->BorderRight
559 - 4 - pictdata
.xsize
- 3) / txwd
;
561 cw
->cols
= (w
->Width
- w
->BorderLeft
- w
->BorderRight
564 cw
->cols
= (w
->Width
- w
->BorderLeft
- w
->BorderRight
- 4)
572 * Clear the right side & bottom. Parts of letters are not
574 * amii_cl_end if window shrinks and columns decrease.
577 if (WINVERS_AMII
|| WINVERS_AMIV
) {
578 amii_setfillpens(w
, cw
->type
);
579 SetDrMd(w
->RPort
, JAM2
);
580 x2
= w
->Width
- w
->BorderRight
;
581 y2
= w
->Height
- w
->BorderBottom
;
582 x1
= x2
- w
->IFont
->tf_XSize
- w
->IFont
->tf_XSize
;
584 if (x1
< w
->BorderLeft
)
586 RectFill(w
->RPort
, x1
, y1
, x2
, y2
);
588 y1
= y1
- w
->IFont
->tf_YSize
;
589 RectFill(w
->RPort
, x1
, y1
, x2
, y2
);
590 RefreshWindowFrame(w
);
593 /* Make the prop gadget the right size and place */
595 DisplayData(win
, topidx
);
596 SetPropInfo(w
, gd
, wheight
, totalvis
, topidx
);
598 /* Force the window to a text line boundary <= to
599 * what the user dragged it to. This eliminates
600 * having to clean things up on the bottom edge.
603 SizeWindow(w
, 0, (wheight
* txh
) + w
->BorderTop
604 + w
->BorderBottom
+ 2 - w
->Height
);
606 /* Don't do next NEWSIZE, we caused it */
608 oldsecs
= oldmics
= 0;
612 #define CTRL(x) ((x) - '@')
613 morc
= code
= map_menu_cmd(code
);
614 if (code
== MENU_SELECT_ALL
) {
615 if (how
== PICK_ANY
) {
616 amip
= cw
->menu
.items
;
618 if (amip
->canselect
&& amip
->selector
) {
620 * Select those yet unselected
621 * and apply count if necessary
623 if (!amip
->selected
) {
624 amip
->selected
= TRUE
;
627 reset_counting
= TRUE
;
629 * This makes the assumption that
630 * the string is in format "X - foo"
631 * with additional selecting and
633 * data in front (size SOFF)
635 amip
->str
[SOFF
+ 2] = '#';
638 amip
->str
[SOFF
+ 2] = '-';
644 DisplayData(win
, topidx
);
646 } else if (code
== MENU_UNSELECT_ALL
) {
647 if (how
== PICK_ANY
) {
648 amip
= cw
->menu
.items
;
650 if (amip
->selected
) {
651 amip
->selected
= FALSE
;
653 amip
->str
[SOFF
+ 2] = '-';
657 DisplayData(win
, topidx
);
659 } else if (code
== MENU_INVERT_ALL
) {
660 if (how
== PICK_ANY
) {
661 amip
= cw
->menu
.items
;
663 if (amip
->canselect
&& amip
->selector
) {
664 amip
->selected
= !amip
->selected
;
665 if (counting
&& amip
->selected
) {
667 amip
->str
[SOFF
+ 2] = '#';
668 reset_counting
= TRUE
;
671 amip
->str
[SOFF
+ 2] = '-';
676 DisplayData(win
, topidx
);
678 } else if (code
== MENU_SELECT_PAGE
) {
679 if (how
== PICK_ANY
) {
681 amip
= cw
->menu
.items
;
682 while (amip
&& i
++ < topidx
)
684 for (i
= 0; i
< wheight
&& amip
;
685 i
++, amip
= amip
->next
) {
686 if (amip
->canselect
&& amip
->selector
) {
687 if (!amip
->selected
) {
690 reset_counting
= TRUE
;
691 amip
->str
[SOFF
+ 2] = '#';
694 amip
->str
[SOFF
+ 2] = '-';
697 amip
->selected
= TRUE
;
700 DisplayData(win
, topidx
);
702 } else if (code
== MENU_UNSELECT_PAGE
) {
703 if (how
== PICK_ANY
) {
705 amip
= cw
->menu
.items
;
706 while (amip
&& i
++ < topidx
)
708 for (i
= 0; i
< wheight
&& amip
;
709 i
++, amip
= amip
->next
) {
710 if (amip
->selected
) {
711 amip
->selected
= FALSE
;
713 amip
->str
[SOFF
+ 2] = '-';
716 DisplayData(win
, topidx
);
718 } else if (code
== MENU_INVERT_PAGE
) {
719 if (how
== PICK_ANY
) {
721 amip
= cw
->menu
.items
;
722 while (amip
&& i
++ < topidx
)
724 for (i
= 0; i
< wheight
&& amip
;
725 i
++, amip
= amip
->next
) {
726 if (amip
->canselect
&& amip
->selector
) {
727 amip
->selected
= !amip
->selected
;
728 if (counting
&& amip
->selected
) {
730 amip
->str
[SOFF
+ 2] = '#';
731 reset_counting
= TRUE
;
734 amip
->str
[SOFF
+ 2] = '-';
738 DisplayData(win
, topidx
);
740 } else if (code
== MENU_SEARCH
&& cw
->type
== NHW_MENU
) {
741 if (how
== PICK_ONE
|| how
== PICK_ANY
) {
743 amip
= cw
->menu
.items
;
744 amii_getlin("Search for:", buf
);
745 if (!*buf
|| *buf
== '\033')
748 if (amip
->canselect
&& amip
->selector
&& amip
->str
749 && strstri(&amip
->str
[SOFF
], buf
)) {
750 if (how
== PICK_ONE
) {
751 amip
->selected
= TRUE
;
755 amip
->selected
= !amip
->selected
;
756 if (counting
&& amip
->selected
) {
758 reset_counting
= TRUE
;
759 amip
->str
[SOFF
+ 2] = '#';
762 reset_counting
= TRUE
;
763 amip
->str
[SOFF
+ 2] = '-';
769 DisplayData(win
, topidx
);
770 } else if (how
== PICK_ANY
&& isdigit(code
)
771 && (counting
|| (!counting
&& code
!= '0'))) {
772 if (count
< LARGEST_INT
) {
773 count
= count
* 10 + (long) (code
- '0');
774 if (count
> LARGEST_INT
)
778 reset_counting
= FALSE
;
780 reset_counting
= TRUE
;
782 sprintf(countString
, "Count: %d", count
);
785 } else if (code
== CTRL('D') || code
== CTRL('U')
786 || code
== MENU_NEXT_PAGE
787 || code
== MENU_PREVIOUS_PAGE
788 || code
== MENU_FIRST_PAGE
789 || code
== MENU_LAST_PAGE
) {
792 for (gd
= w
->FirstGadget
; gd
&& gd
->GadgetID
!= 1;)
796 panic("Can't find scroll gadget");
798 endcnt
= wheight
; /* /2; */
802 if (code
== MENU_FIRST_PAGE
) {
804 } else if (code
== MENU_LAST_PAGE
) {
805 topidx
= cw
->maxrow
- wheight
;
807 for (i
= 0; i
< endcnt
; ++i
) {
808 if (code
== CTRL('D') || code
== MENU_NEXT_PAGE
) {
809 if (topidx
+ wheight
< cw
->maxrow
)
813 } else if (code
= CTRL('U')
814 || code
== MENU_PREVIOUS_PAGE
) {
821 /* Make prop gadget the right size and place */
823 DisplayData(win
, topidx
);
824 SetPropInfo(w
, gd
, wheight
, totalvis
, topidx
);
825 oldsecs
= oldmics
= 0;
826 } else if (code
== '\b') {
827 for (gd
= w
->FirstGadget
; gd
&& gd
->GadgetID
!= 1;)
831 panic("Can't find scroll gadget");
833 if (topidx
- wheight
- 2 < 0) {
836 topidx
-= wheight
- 2;
838 DisplayData(win
, topidx
);
839 SetPropInfo(w
, gd
, wheight
, totalvis
, topidx
);
840 oldsecs
= oldmics
= 0;
841 } else if (code
== ' ') {
842 for (gd
= w
->FirstGadget
; gd
&& gd
->GadgetID
!= 1;)
846 panic("Can't find scroll gadget");
848 if (topidx
+ wheight
>= cw
->maxrow
) {
852 /* If there are still lines to be seen */
854 if (cw
->maxrow
> topidx
+ wheight
) {
856 topidx
+= wheight
- 2;
859 DisplayData(win
, topidx
);
860 SetPropInfo(w
, gd
, wheight
, totalvis
, topidx
);
862 oldsecs
= oldmics
= 0;
864 } else if (code
== '\n' || code
== '\r') {
865 for (gd
= w
->FirstGadget
; gd
&& gd
->GadgetID
!= 1;)
869 panic("Can't find scroll gadget");
871 /* If all line displayed, we are done */
873 if (topidx
+ wheight
>= cw
->maxrow
) {
877 /* If there are still lines to be seen */
879 if (cw
->maxrow
> topidx
+ 1) {
881 DisplayData(win
, topidx
);
882 SetPropInfo(w
, gd
, wheight
, totalvis
, topidx
);
884 oldsecs
= oldmics
= 0;
886 } else if (code
== '\33') {
888 reset_counting
= TRUE
;
893 int selected
= FALSE
;
894 for (amip
= cw
->menu
.items
; amip
; amip
= amip
->next
) {
895 if (amip
->selector
== code
) {
898 amip
->selected
= !amip
->selected
;
899 if (counting
&& amip
->selected
) {
901 reset_counting
= TRUE
;
902 amip
->str
[SOFF
+ 2] = '#';
905 reset_counting
= TRUE
;
906 amip
->str
[SOFF
+ 2] = '-';
909 } else if (amip
->gselector
== code
) {
910 amip
->selected
= !amip
->selected
;
913 reset_counting
= TRUE
;
914 amip
->str
[SOFF
+ 2] = '#';
917 reset_counting
= TRUE
;
918 amip
->str
[SOFF
+ 2] = '-';
924 DisplayData(win
, topidx
);
929 if (win
== WIN_INVEN
) {
930 lastinvent
.MinX
= w
->LeftEdge
;
931 lastinvent
.MinY
= w
->TopEdge
;
932 lastinvent
.MaxX
= w
->Width
;
933 lastinvent
.MaxY
= w
->Height
;
934 } else if (win
== WIN_MESSAGE
) {
935 lastmsg
.MinX
= w
->LeftEdge
;
936 lastmsg
.MinY
= w
->TopEdge
;
937 lastmsg
.MaxX
= w
->Width
;
938 lastmsg
.MaxY
= w
->Height
;
945 if (win
== WIN_MESSAGE
)
947 for (gd
= w
->FirstGadget
; gd
&& gd
->GadgetID
!= 1;)
950 pip
= (struct PropInfo
*) gd
->SpecialInfo
;
951 totalvis
= CountLines(win
);
952 hidden
= max(totalvis
- wheight
, 0);
953 aidx
= (((ULONG
) hidden
* pip
->VertPot
) + (MAXPOT
/ 2)) >> 16;
955 DisplayData(win
, topidx
= aidx
);
959 for (gd
= w
->FirstGadget
; gd
&& gd
->GadgetID
!= 1;)
962 pip
= (struct PropInfo
*) gd
->SpecialInfo
;
963 totalvis
= CountLines(win
);
964 hidden
= max(totalvis
- wheight
, 0);
965 aidx
= (((ULONG
) hidden
* pip
->VertPot
) + (MAXPOT
/ 2)) >> 16;
967 DisplayData(win
, topidx
= aidx
);
971 if (win
== WIN_MESSAGE
|| (win
== WIN_INVEN
&& alwaysinvent
))
976 if ((code
== SELECTUP
|| code
== SELECTDOWN
)
977 && cw
->type
== NHW_MENU
&& how
!= PICK_NONE
) {
978 /* Which one is the mouse pointing at? */
980 aidx
= ((my
- w
->BorderTop
- 1) / txh
) + topidx
;
982 /* If different lines, don't select double click */
989 /* If releasing, check for double click */
991 if (code
== SELECTUP
) {
992 amip
= find_menu_item(cw
, aidx
);
994 if (DoubleClick(oldsecs
, oldmics
, secs
, mics
)) {
1000 amip
= find_menu_item(cw
, oidx
);
1003 reset_counting
= TRUE
;
1004 if (amip
->canselect
&& amip
->selector
)
1005 amip
->str
[SOFF
+ 2] = '-';
1007 if (counting
&& amip
->selected
&& amip
->canselect
1008 && amip
->selector
) {
1009 amip
->count
= count
;
1010 reset_counting
= TRUE
;
1011 amip
->str
[SOFF
+ 2] = '#';
1013 DisplayData(win
, topidx
);
1014 } else if (aidx
- topidx
< wheight
&& aidx
< cw
->maxrow
1015 && code
== SELECTDOWN
) {
1016 /* Remove old highlighting if visible */
1018 amip
= find_menu_item(cw
, oidx
);
1019 if (amip
&& oidx
!= aidx
1020 && (oidx
> topidx
&& oidx
- topidx
< wheight
)) {
1021 if (how
!= PICK_ANY
) {
1024 reset_counting
= TRUE
;
1025 if (amip
->canselect
&& amip
->selector
)
1026 amip
->str
[SOFF
+ 2] = '-';
1030 amip
= find_menu_item(cw
, aidx
);
1032 if (amip
&& amip
->canselect
&& amip
->selector
1033 && how
!= PICK_NONE
) {
1035 if (!DoubleClick(oldsecs
, oldmics
, secs
, mics
)) {
1036 amip
->selected
= !amip
->selected
;
1037 if (counting
&& amip
->selected
) {
1038 amip
->count
= count
;
1039 reset_counting
= TRUE
;
1040 amip
->str
[SOFF
+ 2] = '#';
1043 reset_counting
= TRUE
;
1044 if (amip
->canselect
&& amip
->selector
)
1045 amip
->str
[SOFF
+ 2] = '-';
1053 DisplayData(win
, topidx
);
1060 if (!counting
&& morc
== '\33') {
1061 amip
= cw
->menu
.items
;
1063 if (amip
->canselect
&& amip
->selector
) {
1064 amip
->selected
= FALSE
;
1066 amip
->str
[SOFF
+ 2] = '-';
1071 if (reset_counting
) {
1079 /* Force a cursor reposition before next message output */
1080 if (win
== WIN_MESSAGE
)
1082 return (make_menu_items(cw
, retmip
));
1090 register struct amii_WinDesc
*cw
;
1091 register struct Window
*w
;
1092 register struct Gadget
*gd
;
1093 unsigned long hidden
, aidx
, wheight
;
1094 struct PropInfo
*pip
;
1096 if (win
== WIN_ERR
|| !(cw
= amii_wins
[win
]) || !(w
= cw
->win
))
1099 for (gd
= w
->FirstGadget
; gd
&& gd
->GadgetID
!= 1;)
1100 gd
= gd
->NextGadget
;
1106 (w
->Height
- w
->BorderTop
- w
->BorderBottom
- 2) / w
->RPort
->TxHeight
;
1108 pip
= (struct PropInfo
*) gd
->SpecialInfo
;
1109 totalvis
= CountLines(win
);
1110 hidden
= max(totalvis
- wheight
, 0);
1111 aidx
= (((ULONG
) hidden
* pip
->VertPot
) + (MAXPOT
/ 2)) >> 16;
1112 clear_nhwindow(win
);
1113 DisplayData(win
, aidx
);
1123 register struct amii_WinDesc
*cw
;
1124 register struct Window
*w
;
1125 register int i
, disprow
, len
;
1128 if (win
== WIN_ERR
|| !(cw
= amii_wins
[win
]) || !(w
= cw
->win
)) {
1129 panic(winpanicstr
, win
, "No Window in FindLine");
1131 txwd
= w
->RPort
->TxWidth
;
1133 if (win
== WIN_INVEN
) {
1134 cw
->cols
= (w
->Width
- w
->BorderLeft
- w
->BorderRight
- 4
1135 - pictdata
.xsize
- 3) / txwd
;
1137 cw
->cols
= (w
->Width
- w
->BorderLeft
- w
->BorderRight
- 4) / txwd
;
1139 cw
->cols
= (w
->Width
- w
->BorderLeft
- w
->BorderRight
- 4) / txwd
;
1143 for (col
= i
= 0; line
> disprow
&& i
< cw
->maxrow
; ++i
) {
1144 t
= cw
->data
[i
] + SOFF
;
1145 if (cw
->data
[i
][1] >= 0) {
1152 if (col
+ len
> cw
->cols
)
1153 len
= cw
->cols
- col
;
1155 if (!t
[len
] || t
[len
] == ' ')
1160 while (*t
&& *t
!= ' ') {
1184 amii_menu_item
*mip
;
1186 register struct amii_WinDesc
*cw
;
1187 register struct Window
*w
;
1188 register int i
, disprow
, len
;
1191 if (win
== WIN_ERR
|| !(cw
= amii_wins
[win
]) || !(w
= cw
->win
)) {
1192 panic(winpanicstr
, win
, "No Window in CountLines");
1195 txwd
= w
->RPort
->TxWidth
;
1197 if (win
== WIN_INVEN
) {
1198 cw
->cols
= (w
->Width
- w
->BorderLeft
- w
->BorderRight
- 4
1199 - pictdata
.xsize
- 3) / txwd
;
1201 cw
->cols
= (w
->Width
- w
->BorderLeft
- w
->BorderRight
- 4) / txwd
;
1203 cw
->cols
= (w
->Width
- w
->BorderLeft
- w
->BorderRight
- 4) / txwd
;
1206 disprow
= cw
->maxrow
;
1207 mip
= cw
->menu
.items
;
1208 for (col
= i
= 0; i
< cw
->maxrow
; ++i
) {
1209 t
= cw
->data
[i
] + SOFF
;
1210 if (cw
->type
== NHW_MESSAGE
&& cw
->data
[i
][SEL_ITEM
] < 0)
1216 if (col
+ len
> cw
->cols
)
1217 len
= cw
->cols
- col
;
1219 if (!t
[len
] || t
[len
] == ' ')
1224 while (*t
&& *t
!= ' ') {
1244 DisplayData(win
, start
)
1249 amii_menu_item
*mip
;
1251 register struct amii_WinDesc
*cw
;
1252 register struct Window
*w
;
1253 register struct RastPort
*rp
;
1254 register int i
, disprow
, len
, wheight
;
1255 int whichcolor
= -1;
1258 if (win
== WIN_ERR
|| !(cw
= amii_wins
[win
]) || !(w
= cw
->win
)) {
1259 panic(winpanicstr
, win
, "No Window in DisplayData");
1264 if (WINVERS_AMIV
&& win
== WIN_INVEN
) {
1265 wheight
= (w
->Height
- w
->BorderTop
- w
->BorderBottom
- 2)
1266 / max(rp
->TxHeight
, pictdata
.ysize
+ 3);
1269 (w
->Height
- w
->BorderTop
- w
->BorderBottom
- 2) / rp
->TxHeight
;
1275 if (win
== WIN_INVEN
) {
1276 cw
->cols
= (w
->Width
- w
->BorderLeft
- w
->BorderRight
- 4
1277 - pictdata
.xsize
- 3) / txwd
;
1279 cw
->cols
= (w
->Width
- w
->BorderLeft
- w
->BorderRight
- 4) / txwd
;
1281 cw
->cols
= (w
->Width
- w
->BorderLeft
- w
->BorderRight
- 4) / txwd
;
1284 /* Get the real line to display at */
1285 start
= FindLine(win
, start
);
1287 mip
= cw
->menu
.items
;
1288 for (i
= 0; mip
&& i
< start
; ++i
) {
1292 /* Skip any initial response to a previous line */
1293 if (cw
->type
== NHW_MESSAGE
&& mip
&& mip
->selected
< 0)
1295 if (WINVERS_AMIV
&& cw
->type
== NHW_MESSAGE
)
1296 SetAPen(rp
, amii_msgAPen
);
1298 for (disprow
= i
= start
; disprow
< wheight
+ start
; i
++) {
1299 /* Just erase unused lines in the window */
1300 if (i
>= cw
->maxrow
) {
1301 if (WINVERS_AMIV
&& win
== WIN_INVEN
) {
1302 amii_curs(win
, 0, disprow
- start
);
1303 amiga_print_glyph(win
, 0, NO_GLYPH
);
1305 amii_curs(win
, 1, disprow
- start
);
1311 /* Any string with a highlighted attribute goes
1312 * onto the end of the current line in the message window.
1314 if (cw
->type
== NHW_MESSAGE
)
1315 SetAPen(rp
, cw
->data
[i
][SEL_ITEM
] < 0 ? C_RED
: amii_msgAPen
);
1317 /* Selected text in the message window goes onto the end of the
1319 if (cw
->type
!= NHW_MESSAGE
|| cw
->data
[i
][SEL_ITEM
] >= 0) {
1320 amii_curs(win
, 1, disprow
- start
);
1321 if (WINVERS_AMIV
&& win
== WIN_INVEN
) {
1323 amiga_print_glyph(win
, 0, mip
->glyph
);
1324 amii_curs(win
, 1, disprow
- start
);
1329 /* If this entry is to be highlighted, do so */
1330 if (mip
&& mip
->selected
!= 0) {
1331 if (whichcolor
!= 1) {
1334 SetAPen(rp
, amii_menuBPen
);
1335 SetBPen(rp
, C_BLUE
);
1337 SetAPen(rp
, C_BLUE
);
1338 SetBPen(rp
, amii_menuAPen
);
1342 } else if (whichcolor
!= 2) {
1344 if (cw
->type
== NHW_MESSAGE
) {
1345 SetAPen(rp
, amii_msgAPen
);
1346 SetBPen(rp
, amii_msgBPen
);
1347 } else if (cw
->type
== NHW_MENU
) {
1348 SetAPen(rp
, amii_menuAPen
);
1349 SetBPen(rp
, amii_menuBPen
);
1350 } else if (cw
->type
== NHW_TEXT
) {
1351 SetAPen(rp
, amii_textAPen
);
1352 SetBPen(rp
, amii_textBPen
);
1357 /* Next line out, wrap if too long */
1359 t
= cw
->data
[i
] + SOFF
;
1364 if (len
> (cw
->cols
- col
))
1365 len
= cw
->cols
- col
;
1367 if (!t
[len
] || t
[len
] == ' ')
1372 Text(rp
, t
, cw
->cols
- col
);
1373 while (*t
&& *t
!= ' ') {
1382 amii_cl_end(cw
, col
);
1385 /* Stop at the bottom of the window */
1386 if (disprow
> wheight
+ start
)
1390 amii_curs(win
, 1, disprow
- start
- 1);
1391 if (mip
&& win
== WIN_INVEN
&& WINVERS_AMIV
) {
1392 /* Erase any previous glyph drawn here. */
1393 amiga_print_glyph(win
, 0, NO_GLYPH
);
1394 amii_curs(win
, 1, disprow
- start
- 1);
1401 if (cw
->type
== NHW_MESSAGE
) {
1402 SetAPen(rp
, amii_msgBPen
);
1403 SetBPen(rp
, amii_msgBPen
);
1404 } else if (cw
->type
== NHW_MENU
) {
1405 SetAPen(rp
, amii_menuBPen
);
1406 SetBPen(rp
, amii_menuBPen
);
1407 } else if (cw
->type
== NHW_TEXT
) {
1408 SetAPen(rp
, amii_textBPen
);
1409 SetBPen(rp
, amii_textBPen
);
1411 amii_cl_end(cw
, col
);
1416 RefreshWindowFrame(w
);
1421 SetPropInfo(win
, gad
, vis
, total
, top
)
1422 register struct Window
*win
;
1423 register struct Gadget
*gad
;
1424 register long vis
, total
, top
;
1427 register long hidden
;
1428 register int body
, pot
;
1430 hidden
= max(total
- vis
, 0);
1432 /* Force the last section to be just to the bottom */
1437 /* Scale the body position. */
1438 /* 2 lines overlap */
1440 if (hidden
> 0 && total
> 2)
1441 body
= (ULONG
)((vis
- 2) * MAXBODY
) / (total
- 2);
1446 pot
= (ULONG
)(top
* MAXPOT
) / hidden
;
1450 mflags
= AUTOKNOB
| FREEVERT
;
1451 #ifdef INTUI_NEW_LOOK
1452 if (IntuitionBase
->LibNode
.lib_Version
>= 37) {
1453 mflags
|= PROPNEWLOOK
;
1457 NewModifyProp(gad
, win
, NULL
, mflags
, 0, pot
, MAXBODY
, body
, 1);