home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * Iteraction library - pop up queries. *
- * *
- * Written by Gershon Elber, Oct. 1990 *
- *******************************************************************************
- * Type of queries currently supported: *
- * 1. Continue query - informative pop up message. Wait for the user. *
- * 2. Yes/No query - pop up question. Wait for yes/no from the user. *
- * 3. Line query - pop up a messgae. Wait for the user to type a full line. *
- *******************************************************************************
- * History: *
- * 3 Oct 90 - Version 1.0 by Gershon Elber. *
- ******************************************************************************/
-
- #include <string.h>
- #include <stdio.h>
- #include "intr_loc.h"
- #include "intr_gr.h"
-
- #define MIN_CONTINUE_QUERY_WIDTH 150
- #define CONTINUE_QUERY_HEIGHT 90
- #define CONTINUE_STR_HEIGHT 20
- #define CONTINUE_STR_WIDTH 80
-
- #define MIN_CONTINUE2_QUERY_WIDTH 150
- #define CONTINUE2_QUERY_HEIGHT 40
-
- #define MIN_YES_NO_QUERY_WIDTH 180
- #define YES_NO_QUERY_HEIGHT 90
- #define YES_NO_STR_HEIGHT 20
- #define YES_NO_STR_WIDTH 50
-
- #define MIN_LINE_QUERY_WIDTH 150
- #define LINE_QUERY_HEIGHT 70
- #define LINE_WINDOW_LEN 22
-
- #define LIST_QUERY_BORDER 8
- #ifdef DJGCC
- #define LIST_QUERY_BASE_LINE 16
- #else
- #define LIST_QUERY_BASE_LINE 12
- #endif /* DJGCC */
-
- static int GRLastColor = 0; /* GR Color set before query. */
- static IntrBType HasHeader = FALSE;
-
- static void QueryProlog(int WindowID, int QueryWidth, int QueryHeight,
- IntrCursorShapeStruct *Cursor, IntrColorType FrameWidth,
- IntrColorType FrameColor, IntrColorType BackColor,
- int *Xmin, int *Ymin, int *Xmax, int *Ymax,
- IntrScrlBarType ScrlBar);
- static void QueryEpilog(IntrCursorShapeStruct *Cursor);
- static int MatchPosition(int x, int y, int Top, int Left,
- int Bottom, int Right, int Space, int ItemHeight);
- static void ListQueryDrawItems(char **StrEntries, int SizeOfEntry,
- int NumOfEntries,
- int FirstDisplayed, int NumOfDisplayedEntries,
- int Left, int Top, int Right, int Bottom,
- IntrColorType BackColor, IntrColorType ForeColor);
-
- /****************************************************************************
- * Do all common to all queries on entry. *
- * Attempt will be made to place the message in the middle of the specified *
- * window windowID if possible, or middle of screen if WindowID = 0. *
- * Width and Height specifies the size of the query window and FrameWidth *
- * specifies its FrameWidth. FrameColor and BackColor set the colors. *
- ****************************************************************************/
- static void QueryProlog(int WindowID, int QueryWidth, int QueryHeight,
- IntrCursorShapeStruct *Cursor, IntrColorType FrameWidth,
- IntrColorType FrameColor, IntrColorType BackColor,
- int *Xmin, int *Ymin, int *Xmax, int *Ymax,
- IntrScrlBarType ScrlBar)
- {
- IntrBBoxStruct *BBox;
- int QueryCenterX, QueryCenterY;
-
- /* Save current graphic state. */
- if (Cursor != NULL) {
- IntrPushCursorType();
- IntrSetCursorType(Cursor);
- }
-
- GRPushViewPort();
- _GRSetViewPort(0, 0, GRScreenMaxX, GRScreenMaxY);
-
- GRPushTextSetting();
- GRSetTextJustify(GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_BOTTOM);
- GRSetSTextStyle(GR_FONT_DEFAULT, GR_HORIZ_DIR, GR_TEXT_MAG_1);
-
- GRLastColor = GRGetColor();
-
- /* Find center of query prefered position and find BBox for query. */
- if (WindowID > 0) {
- BBox = IntrWndwGetBBox(WindowID);
-
- QueryCenterX = (BBox -> Xmax + BBox -> Xmin) >> 1;
- QueryCenterY = (BBox -> Ymax + BBox -> Ymin) >> 1;
- }
- else
- switch (WindowID) {
- case INTR_WNDW_PLACE_LEFT:
- QueryCenterX = GRScreenMaxX >> 2;
- QueryCenterY = GRScreenMaxY >> 1;
- break;
- case INTR_WNDW_PLACE_RIGHT:
- QueryCenterX = (GRScreenMaxX >> 1) + (GRScreenMaxX >> 2);
- QueryCenterY = GRScreenMaxY >> 1;
- break;
- case INTR_WNDW_PLACE_CENTER:
- default:
- QueryCenterX = GRScreenMaxX >> 1;
- QueryCenterY = GRScreenMaxY >> 1;
- break;
- }
-
- *Xmin = QueryCenterX - (QueryWidth >> 1);
- *Ymin = QueryCenterY - (QueryHeight >> 1);
- *Xmax = *Xmin + QueryWidth;
- *Ymax = *Ymin + QueryHeight;
- _IntrBoundBBox(Xmin, Ymin, Xmax, Ymax, FrameWidth); /* To screen coords. */
-
- _IntrWndwDrawFrame(*Xmin, *Xmax, *Ymin, *Ymax, FrameWidth,
- FrameColor, TRUE, FrameColor, INTR_SCRLBAR_NONE,
- FrameColor, ScrlBar, TRUE);
- IntrAllocColor(BackColor, INTR_INTENSITY_HIGH);
- GRSBar(*Xmin, *Ymin, *Xmax, *Ymax);
- }
-
- /****************************************************************************
- * Pop current graphic state. *
- ****************************************************************************/
- static void QueryEpilog(IntrCursorShapeStruct *Cursor)
- {
- if (_IntrSaveBelow) {
- _IntrRestoreWindow();
- if (HasHeader) {
- _IntrRestoreWindow();
- HasHeader = FALSE;
- }
- }
-
- GRPopViewPort();
- GRPopTextSetting();
- GRSetColor(GRLastColor);
-
- if (Cursor != NULL)
- IntrPopCursorType();
- }
-
- /****************************************************************************
- * Perform simple clipping and translation to make sure entire bbox is in *
- * the screen boundary. *
- ****************************************************************************/
- void _IntrBoundBBox(int *Xmin, int *Ymin, int *Xmax, int *Ymax, int Width)
- {
- if (*Xmin < Width) {
- *Xmax -= *Xmin - Width;
- *Xmin = Width;
- }
- if (*Xmax > GRScreenMaxX - Width) {
- *Xmin -= *Xmax - GRScreenMaxX + Width;
- *Xmax = GRScreenMaxX - Width;
- }
- if (*Ymin < Width) {
- *Ymax -= *Ymin - Width;
- *Ymin = Width;
- }
- if (*Ymax > GRScreenMaxY - Width) {
- *Ymin -= *Ymax - GRScreenMaxY + Width;
- *Ymax = GRScreenMaxY - Width;
- }
- }
-
- /****************************************************************************
- * Routine to display one string and return after a continue button has been *
- * pressed. Used to inform the user on some status. *
- * Attempt will be made to place the message in the middle of the specified *
- * window if possible, or middle of screen if WindowID = 0. *
- ****************************************************************************/
- void IntrQueryContinue(char *Question,
- IntrColorType FrameColor,
- IntrColorType BackColor,
- IntrColorType ForeColor,
- IntrColorType XorColor,
- int FrameWidth,
- IntrCursorShapeStruct *Cursor,
- int WindowID)
- {
- IntrEventType Event;
- int x, y, TextWidth, NewMatch, Color, QueryWidth, QueryHeight,
- Xmin, Ymin, Xmax, Ymax, ContXmin, ContYmin, ContXmax, ContYmax,
- Exit = FALSE,
- Match = -1;
-
- GRPushTextSetting();
- GRSetSTextStyle(GR_FONT_DEFAULT, GR_HORIZ_DIR, GR_TEXT_MAG_1);
- TextWidth = GRGetTextWidth(Question);
- QueryWidth = MAX(TextWidth + 10, MIN_CONTINUE_QUERY_WIDTH);
- QueryHeight = CONTINUE_QUERY_HEIGHT;
- GRPopTextSetting();
-
- QueryProlog(WindowID, QueryWidth, QueryHeight, Cursor, FrameWidth,
- FrameColor, BackColor, &Xmin, &Ymin, &Xmax, &Ymax,
- INTR_SCRLBAR_NONE);
-
- /* Compute spaces between the Continue button and question. */
- y = ((Ymax - Ymin) - CONTINUE_STR_HEIGHT - GRGetTextHeight(Question)) / 3;
-
- /* Draw the "continue" button. */
- ContXmin = (Xmin + Xmax - CONTINUE_STR_WIDTH) >> 1;
- ContXmax = (Xmin + Xmax + CONTINUE_STR_WIDTH) >> 1;
- ContYmax = Ymax - y;
- ContYmin = ContYmax - CONTINUE_STR_HEIGHT;
- _IntrWndwDrawFrame(ContXmin, ContXmax, ContYmin, ContYmax, FrameWidth,
- FrameColor, FALSE, FrameColor, INTR_SCRLBAR_NONE,
- FrameColor, INTR_SCRLBAR_NONE, TRUE);
- IntrAllocColor(BackColor, INTR_INTENSITY_LOW);
- GRSBar(ContXmin, ContYmin, ContXmax, ContYmax);
- Color = IntrAllocColor(ForeColor, INTR_INTENSITY_VHIGH);
- GRSetTextJustify(GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER);
-
- GRSetSTextStyle(GR_FONT_DEFAULT, GR_HORIZ_DIR, GR_TEXT_MAG_1);
- GRSTextShadow((ContXmin + ContXmax) >> 1, (ContYmin + ContYmax) >> 1,
- Color, "Continue");
-
- /* Put the question in: */
- GRSTextShadow((Xmin + Xmax) >> 1, Ymin + y, Color, Question);
-
- /* Put the mouse on the middle of the CONTINUE box: */
- x = GRCurrentCursorX = (ContXmin + ContXmax) >> 1;
- y = GRCurrentCursorY = (ContYmin + ContYmax) >> 1;
- Event = INTR_EVNT_MOVE;/* Emulate move event, and test current position. */
-
- while (!Exit) {
- switch (Event) {
- case INTR_EVNT_KEY:
- if (x == 'c' || x == 'C') {
- Match = 1;
- Exit = TRUE;
- break;
- }
- break;
- case INTR_EVNT_SELECT:
- if (Match >= 0)
- Exit = TRUE;
- else {
- GRTone(1000, 100); /* Do some noise... */
- GRTone( 300, 200);
- }
- break;
- case INTR_EVNT_ABORT: /* Ignored. */
- GRTone(1000, 100); /* Do some noise... */
- GRTone( 300, 200);
- break;
- case INTR_EVNT_MOVE:
- if (x >= ContXmin && x <= ContXmax &&
- y >= ContYmin && y <= ContYmax)
- NewMatch = 1;
- else
- NewMatch = -1; /* No match. */
- if (NewMatch != Match) {
- IntrAllocColor(XorColor, INTR_INTENSITY_VHIGH);
-
- /* If something was selected before - uninvert it: */
- if (Match == 1)
- GRXORRectangle(ContXmin, ContYmin, ContXmax, ContYmax);
- Match = NewMatch;
-
- /*Invert new selection if there is one: */
- if (Match == 1)
- GRXORRectangle(ContXmin, ContYmin, ContXmax, ContYmax);
- }
- break;
- }
- if (!Exit) Event = IntrGetEventWait(&x, &y);
- }
-
- QueryEpilog(Cursor);
- }
-
- /****************************************************************************
- * Same as continue but call ExecFunc instead of event waiting. *
- ****************************************************************************/
- void IntrQueryContinue2(char *Question,
- void (* ExecFunc)(void),
- IntrColorType FrameColor,
- IntrColorType BackColor,
- IntrColorType ForeColor,
- int FrameWidth,
- IntrCursorShapeStruct *Cursor,
- int WindowID)
- {
- int TextWidth, QueryWidth, QueryHeight, Xmin, Ymin, Xmax, Ymax;
-
- GRPushTextSetting();
- GRSetSTextStyle(GR_FONT_DEFAULT, GR_HORIZ_DIR, GR_TEXT_MAG_1);
- TextWidth = GRGetTextWidth(Question);
- QueryWidth = MAX(TextWidth + 10, MIN_CONTINUE2_QUERY_WIDTH);
- QueryHeight = CONTINUE2_QUERY_HEIGHT;
- GRPopTextSetting();
-
- QueryProlog(WindowID, QueryWidth, QueryHeight, Cursor,
- FrameWidth, FrameColor, BackColor, &Xmin, &Ymin, &Xmax, &Ymax,
- INTR_SCRLBAR_NONE);
-
- /* Put the question in: */
- GRSetTextJustify(GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER);
- GRSTextShadow((Xmin + Xmax) >> 1, (Ymin + Ymax) >> 1,
- IntrAllocColor(ForeColor, INTR_INTENSITY_VHIGH), Question);
-
- ExecFunc();
-
- QueryEpilog(Cursor);
- }
-
- /****************************************************************************
- * Routine to display one string and return TRUE if YES is selected FALSE if *
- * NO. select must be made using the Select key, and Abort key is ignored. *
- * Attempt will be made to place the message in the middle of the specified *
- * window if possible, or middle of screen if WindowID = 0. *
- ****************************************************************************/
- IntrBType IntrQueryYesNo(char *Question,
- IntrColorType FrameColor,
- IntrColorType BackColor,
- IntrColorType ForeColor,
- IntrColorType XorColor,
- int FrameWidth,
- IntrCursorShapeStruct *Cursor,
- int WindowID)
- {
- IntrEventType Event;
- int x, y, TextWidth, Color, NewMatch, QueryWidth, QueryHeight,
- Xmin, Ymin, Xmax, Ymax, Dx4, YesXmin, YesYmin, YesXmax, YesYmax,
- NoXmin, NoYmin, NoXmax, NoYmax,
- Exit = FALSE,
- Match = -1;
-
- GRPushTextSetting();
- GRSetSTextStyle(GR_FONT_DEFAULT, GR_HORIZ_DIR, GR_TEXT_MAG_1);
- TextWidth = GRGetTextWidth(Question);
- QueryWidth = MAX(TextWidth + 10, MIN_YES_NO_QUERY_WIDTH);
- QueryHeight = YES_NO_QUERY_HEIGHT;
- GRPopTextSetting();
-
- QueryProlog(WindowID, QueryWidth, QueryHeight, Cursor,
- FrameWidth, FrameColor, BackColor, &Xmin, &Ymin, &Xmax, &Ymax,
- INTR_SCRLBAR_NONE);
-
- Dx4 = (Xmax - Xmin) >> 2;
-
- y = ((Ymax - Ymin) - YES_NO_STR_HEIGHT - GRGetTextHeight(Question)) / 3;
-
- /* Draw the "yes" button. */
- YesXmin = Xmin + Dx4 - (YES_NO_STR_WIDTH >> 1);
- YesXmax = Xmin + Dx4 + (YES_NO_STR_WIDTH >> 1);
- YesYmax = Ymax - y;
- YesYmin = YesYmax - YES_NO_STR_HEIGHT;
- _IntrWndwDrawFrame(YesXmin, YesXmax, YesYmin, YesYmax, FrameWidth,
- FrameColor, FALSE, FrameColor, INTR_SCRLBAR_NONE,
- FrameColor, INTR_SCRLBAR_NONE, TRUE);
- IntrAllocColor(BackColor, INTR_INTENSITY_LOW);
- GRSBar(YesXmin, YesYmin, YesXmax, YesYmax);
- Color = IntrAllocColor(ForeColor, INTR_INTENSITY_VHIGH);
- GRSetTextJustify(GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER);
- GRSetSTextStyle(GR_FONT_DEFAULT, GR_HORIZ_DIR, GR_TEXT_MAG_1);
- GRSTextShadow((YesXmin + YesXmax) >> 1, (YesYmin + YesYmax) >> 1,
- Color, "Yes");
-
- /* Draw the "no" button. */
- NoXmin = Xmax - Dx4 - (YES_NO_STR_WIDTH >> 1);
- NoXmax = Xmax - Dx4 + (YES_NO_STR_WIDTH >> 1);
- NoYmax = Ymax - y;
- NoYmin = NoYmax - YES_NO_STR_HEIGHT;
- _IntrWndwDrawFrame(NoXmin, NoXmax, NoYmin, NoYmax, FrameWidth,
- FrameColor, FALSE, FrameColor, INTR_SCRLBAR_NONE,
- FrameColor, INTR_SCRLBAR_NONE, TRUE);
- IntrAllocColor(BackColor, INTR_INTENSITY_LOW);
- GRSBar(NoXmin, NoYmin, NoXmax, NoYmax);
- GRSetTextJustify(GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER);
- GRSetSTextStyle(GR_FONT_DEFAULT, GR_HORIZ_DIR, GR_TEXT_MAG_1);
- GRSTextShadow((NoXmin + NoXmax) >> 1, (NoYmin + NoYmax) >> 1, Color, "No");
-
- /* Put the question in: */
- GRSTextShadow((Xmin + Xmax) >> 1, Ymin + y, Color, Question);
-
- /* Put the mouse on the middle of the Yes box: */
- x = GRCurrentCursorX = (YesXmin + YesXmax) >> 1;
- y = GRCurrentCursorY = (YesYmin + YesYmax) >> 1;
- Event = INTR_EVNT_MOVE;/* Emulate move event, and test current position. */
-
- while (!Exit) {
- switch (Event) {
- case INTR_EVNT_KEY:
- if (x == 'y' || x == 'Y') {
- Match = 1;
- Exit = TRUE;
- break;
- }
- if (x == 'n' || x == 'N') {
- Match = 0;
- Exit = TRUE;
- break;
- }
- break;
- case INTR_EVNT_SELECT:
- if (Match >= 0)
- Exit = TRUE;
- else {
- GRTone(1000, 100); /* Do some noise... */
- GRTone( 300, 200);
- }
- break;
- case INTR_EVNT_ABORT: /* Ignored. */
- GRTone(1000, 100); /* Do some noise... */
- GRTone( 300, 200);
- break;
- case INTR_EVNT_MOVE:
- if (x >= YesXmin && x <= YesXmax &&
- y >= YesYmin && y <= YesYmax)
- NewMatch = 1;
- else if (x >= NoXmin && x <= NoXmax &&
- y >= NoYmin && y <= NoYmax)
- NewMatch = 0;
- else
- NewMatch = -1; /* No match. */
- if (NewMatch != Match) {
- IntrAllocColor(XorColor, INTR_INTENSITY_VHIGH);
-
- /* If something was selected before - uninvert it: */
- if (Match == 0)
- GRXORRectangle(NoXmin, NoYmin, NoXmax, NoYmax);
- else if (Match == 1)
- GRXORRectangle(YesXmin, YesYmin, YesXmax, YesYmax);
-
- Match = NewMatch;
-
- /* If something is selected now - invert it: */
- if (Match == 0)
- GRXORRectangle(NoXmin, NoYmin, NoXmax, NoYmax);
- else if (Match == 1)
- GRXORRectangle(YesXmin, YesYmin, YesXmax, YesYmax);
- }
- break;
- }
- if (!Exit) Event = IntrGetEventWait(&x, &y);
- }
-
- QueryEpilog(Cursor);
-
- return Match;
- }
-
- /****************************************************************************
- * Routine to display one string and wait for input string, which is *
- * placed in given buffer. String may be non NULL to begin with. *
- * Attempt will be made to place the message in the middle of the specified *
- * window if possible, or middle of screen if WindowID = 0. *
- * Return the Buffer address. *
- ****************************************************************************/
- char *IntrQueryLine(char *Question,
- char *Buffer,
- int BufferSize,
- IntrColorType FrameColor,
- IntrColorType BackColor,
- IntrColorType ForeColor,
- int FrameWidth,
- int WindowID)
- {
- int x, y, LineWindowLen, TextWidth, QueryWidth, QueryHeight, Color,
- Xmin, Ymin, Xmax, Ymax;
-
- GRPushTextSetting();
- GRSetSTextStyle(GR_FONT_DEFAULT, GR_HORIZ_DIR, GR_TEXT_MAG_1);
- TextWidth = GRGetTextWidth(Question);
- QueryWidth = MAX(TextWidth + 10, MIN_LINE_QUERY_WIDTH);
- QueryHeight = LINE_QUERY_HEIGHT;
- GRPopTextSetting();
-
- QueryProlog(WindowID, QueryWidth, QueryHeight, NULL,
- FrameWidth, FrameColor, BackColor, &Xmin, &Ymin, &Xmax, &Ymax,
- INTR_SCRLBAR_NONE);
-
- /* Put underline for input line: */
- x = Xmin + 20;
- y = Ymax - ((Ymax - Ymin) >> 2) - 10;
-
- GRSetTextJustify(GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER);
- GRSetSTextStyle(GR_FONT_DEFAULT, GR_HORIZ_DIR, GR_TEXT_MAG_1);
- Color = IntrAllocColor(ForeColor, INTR_INTENSITY_VHIGH);
-
- /* Put the question in: */
- GRSTextShadow((Xmin + Xmax) >> 1, Ymin + ((Ymax - Ymin) >> 2), Color,
- Question);
-
- LineWindowLen = (Xmax - Xmin - 40) / GRGetTextWidth("M");
- GRSLine(x,
- y + GRGetTextHeight("M") + 3,
- x + GRGetTextWidth("M") * LineWindowLen,
- y + GRGetTextHeight("M") + 3);
-
- GRGetGraphicLine(0, x, y, Buffer, BufferSize, LineWindowLen,
- IntrAllocColor(ForeColor, INTR_INTENSITY_VHIGH),
- IntrAllocColor(BackColor, INTR_INTENSITY_HIGH));
-
- QueryEpilog(NULL);
-
- return Buffer;
- }
-
- /****************************************************************************
- * Routine to attempt to match given location with one of the elements in *
- * items displayed. Item are displayed from Top to Bottom, Left to Right. *
- * Item is placed with Space between them and border, and has ItemHeight *
- * height. *
- * Returns the index that matches, or -1 if No match. *
- ****************************************************************************/
- static int MatchPosition(int x, int y, int Top, int Left,
- int Bottom, int Right, int Space, int ItemHeight)
- {
- int CurrentY, i;
-
- /* Fast clipping if cursor is not in the menu at all. */
- if (x <= Left || x >= Right || y <= Top || y >= Bottom) return -1;
-
- for (i = 0, CurrentY = Top;
- CurrentY < Bottom;
- CurrentY += Space, i++) {
- if (CurrentY <= y && CurrentY + ItemHeight >= y) return i;
- }
- return -1;
- }
-
- /****************************************************************************
- * Routine to display a list of items and pick one of them. Functionality *
- * of this query is very much like a pop up menu, but number of items is *
- * virtually unlimited - the user can scroll between items. *
- * Header is an optional header for the list query. *
- * StrEntries may be an array of (char *) in which SizeOfEntry is 0 or may *
- * be of type (char *) itself and it will hold all items linearly, each of *
- * size SizeOfEntry. *
- * NumOfEntries holds number of entries in StrEntries - List size. *
- * NumOfDisplayedEntries holds # of entries to be simultaneously displayed. *
- * XXXXColor controls different colors to be used. *
- * FrameWidth sets the frame drawn for the list query width. *
- * Cursor may specify a new cursor to use. *
- * Menu will be poped in the middle of the screen if WindowID == 0 or in the *
- * middle of the specified WindowID. In all cases the menu will be moved so *
- * it will be all visible. *
- ****************************************************************************/
- int IntrQueryList(char *Header,
- char **StrEntries,
- int SizeOfEntry,
- int NumOfEntries,
- int NumOfDisplayedEntries,
- IntrColorType FrameColor,
- IntrColorType BackColor,
- IntrColorType ForeColor,
- IntrColorType XorColor,
- int FrameWidth,
- IntrCursorShapeStruct *Cursor,
- int WindowID)
- {
- int i, MaxLen, QueryWidth, QueryHeight, Xmin, Xmax, Ymin, Ymax, NewIndex,
- x, y, Event, RetVal, ListLeft, ListTop, ListRight, ListBottom,
- MatchIndex = -1,
- FirstDisplayed = 0;
- IntrBType
- Exit = FALSE;
- IntrRType
- DisplayedFraction = ((IntrRType) NumOfDisplayedEntries) / NumOfEntries,
- RelativePosition = 0.0;
- char
- *String = (char *) StrEntries;
-
- /* Find width and height of list query using number of items and their */
- /* maximum entry string length. */
- if (SizeOfEntry == 0) { /* Its an array of pointers to strings. */
- for (i = MaxLen = 0; i < NumOfEntries; i++)
- if (MaxLen < strlen(StrEntries[i]))
- MaxLen = strlen(StrEntries[i]);
- }
- else {
- for (i = MaxLen = 0; i < NumOfEntries; i++)
- if (MaxLen < strlen(&String[i * SizeOfEntry]))
- MaxLen = strlen(&String[i * SizeOfEntry]);
- }
-
- GRPushTextSetting();
- GRSetSTextStyle(GR_FONT_DEFAULT, GR_HORIZ_DIR, GR_TEXT_MAG_1);
- QueryWidth = GRGetTextWidth("M") * MaxLen + (LIST_QUERY_BORDER << 1);
- QueryHeight = NumOfDisplayedEntries * LIST_QUERY_BASE_LINE +
- (LIST_QUERY_BORDER << 1);
- GRPopTextSetting();
-
- QueryProlog(WindowID, QueryWidth, QueryHeight, Cursor,
- FrameWidth, FrameColor, BackColor, &Xmin, &Ymin, &Xmax, &Ymax,
- INTR_SCRLBAR_LEFT);
-
- MatchIndex = -1; /* No match == -1. */
- ListLeft = Xmin + LIST_QUERY_BORDER;
- ListTop = Ymin + LIST_QUERY_BORDER;
- ListRight = Xmax - LIST_QUERY_BORDER;
- ListBottom = Ymax - LIST_QUERY_BORDER;
-
- ListQueryDrawItems(StrEntries, SizeOfEntry, NumOfEntries,
- FirstDisplayed, NumOfDisplayedEntries,
- ListLeft, ListTop, ListRight, ListBottom,
- BackColor, ForeColor);
- if (Header != NULL) {
- HasHeader = TRUE;
- _IntrWndwPutNameHeader(Xmin - FrameWidth - _INTR_SCROLL_BAR_WIDTH - 1,
- Xmax + FrameWidth,
- Ymin - FrameWidth - 2,
- FrameWidth, Header, TRUE, FrameColor,
- ForeColor, BackColor, TRUE);
- }
-
- _IntrUpdateScrollBar(Xmin - _INTR_SCROLL_BAR_WIDTH - 1, Ymin,
- Xmin - 1, Ymax,
- RelativePosition, DisplayedFraction, TRUE, ForeColor);
-
- Event = INTR_EVNT_MOVE;/* Emulate move event, and test current position. */
- x = GRCurrentCursorX = (ListLeft + ListRight) >> 1;
- y = GRCurrentCursorY = (ListTop + ListBottom) >> 1;
- while (!Exit) {
- switch (Event) {
- case INTR_EVNT_SELECT:
- /* We are on list item - need to return its index. */
- if (MatchIndex >= 0) {
- RetVal = MatchIndex + FirstDisplayed;
- Exit = TRUE;
- }
- else if (x >= Xmin - _INTR_SCROLL_BAR_WIDTH && x <= Xmin &&
- y >= Ymin && y <= Ymax) {
- RelativePosition = ((IntrRType) (y - Ymin)) /
- (Ymax - Ymin);
- FirstDisplayed = (int) (RelativePosition * NumOfEntries);
- _IntrUpdateScrollBar(Xmin - _INTR_SCROLL_BAR_WIDTH - 1, Ymin,
- Xmin - 1, Ymax,
- RelativePosition, DisplayedFraction,
- TRUE, ForeColor);
- ListQueryDrawItems(StrEntries, SizeOfEntry, NumOfEntries,
- FirstDisplayed, NumOfDisplayedEntries,
- ListLeft, ListTop, ListRight, ListBottom,
- BackColor, ForeColor);
- }
- break;
- case INTR_EVNT_ABORT:
- RetVal = -1;
- Exit = TRUE;
- break;
- case INTR_EVNT_MOVE:
- IntrAllocColor(XorColor, INTR_INTENSITY_VHIGH);
- NewIndex = MatchPosition(x, y,
- ListTop, ListLeft, ListBottom, ListRight,
- LIST_QUERY_BASE_LINE, GRGetTextHeight("M"));
- if (NewIndex + FirstDisplayed >= NumOfEntries)
- NewIndex = -1;
-
- if (NewIndex != MatchIndex) {
- /* Invert this entry back to original state: */
- if (MatchIndex >= 0)
- GRXORRectangle(ListLeft - 1,
- ListTop + MatchIndex * LIST_QUERY_BASE_LINE - 1,
- ListRight + 1,
- ListTop + GRGetTextHeight("M") + 1 +
- MatchIndex * LIST_QUERY_BASE_LINE);
- MatchIndex = NewIndex;
- /* Invert this entry: */
- if (MatchIndex >= 0)
- GRXORRectangle(ListLeft - 1,
- ListTop + MatchIndex * LIST_QUERY_BASE_LINE - 1,
- ListRight + 1,
- ListTop + GRGetTextHeight("M") + 1 +
- MatchIndex * LIST_QUERY_BASE_LINE);
- }
- break;
- }
- if (!Exit) Event = IntrGetEventWait(&x, &y);
- }
-
- QueryEpilog(Cursor);
-
- return RetVal;
- }
-
- /****************************************************************************
- * Routine to display list of items in the given location and spacing: *
- * All list and area is inverted once drawn. *
- * If SizeOfItem = 0 then Items is assumed to point on array of (char *). *
- ****************************************************************************/
- static void ListQueryDrawItems(char **StrEntries, int SizeOfEntry,
- int NumOfEntries,
- int FirstDisplayed, int NumOfDisplayedEntries,
- int Left, int Top, int Right, int Bottom,
- IntrColorType BackColor, IntrColorType ForeColor)
- {
- int i, Last, Color;
- char
- *String = (char *) StrEntries;
-
- IntrAllocColor(BackColor, INTR_INTENSITY_HIGH);
- GRSBar(Left - 2, Top, Right, Bottom + 1); /* -2, +1 because of shadow. */
-
- Last = MIN(NumOfEntries, FirstDisplayed + NumOfDisplayedEntries);
- Color = IntrAllocColor(ForeColor, INTR_INTENSITY_VHIGH);
- GRSetTextJustify(GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_TOP);
- for (i = FirstDisplayed; i < Last; i++)
- GRSTextShadow(Left, Top + (i - FirstDisplayed) * LIST_QUERY_BASE_LINE,
- Color,
- SizeOfEntry == 0 ? StrEntries[i] : &String[i * SizeOfEntry]);
- }
-