/* ------------- listbox.c ------------ */ #include #include #include #include "dflat.h" static void near writeselection(WINDOW, int, int, RECT *); static void near change_selection(WINDOW, int); static int near selection_in_window(WINDOW, int); int ListBoxProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) { int rtn; static int py = -1; int my = (int) p2 - GetTop(wnd); if (my >= wnd->wlines-wnd->wtop) my = wnd->wlines - wnd->wtop; switch (msg) { case CREATE_WINDOW: rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2); wnd->selection = -1; return rtn; case ADDTEXT: p2 = wnd->wlines == wnd->selection; break; case CLEARTEXT: wnd->selection = -1; break; case SCROLL: rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2); if (!selection_in_window(wnd, wnd->selection)) { if (p1) PostMessage(wnd, LB_SELECTION, wnd->selection+1, FALSE); else PostMessage(wnd, LB_SELECTION, wnd->selection-1, FALSE); } else writeselection(wnd, wnd->selection, TRUE, NULL); return rtn; case KEYBOARD: if (WindowMoving || WindowSizing) break; switch ((int) p1) { case UP: if (wnd->selection > 0) { if (wnd->selection == wnd->wtop) { writeselection(wnd, wnd->selection, FALSE, NULL); --wnd->selection; rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2); PostMessage(wnd, LB_SELECTION, wnd->selection, FALSE); } else { int newsel = wnd->selection-1; if (wnd->wlines == ClientHeight(wnd)) while (*TextLine(wnd, newsel) == LINE) --newsel; PostMessage(wnd, LB_SELECTION, newsel, FALSE); } } return TRUE; case DN: if (wnd->selection < wnd->wlines-1) { if (wnd->selection == wnd->wtop+ClientHeight(wnd)-1) { writeselection(wnd, wnd->selection, FALSE, NULL); wnd->selection++; rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2); PostMessage(wnd, LB_SELECTION, wnd->selection, FALSE); } else { int newsel = wnd->selection+1; if (wnd->wlines == ClientHeight(wnd)) while (*TextLine(wnd, newsel) == LINE) newsel++; PostMessage(wnd, LB_SELECTION, newsel, FALSE); } } return TRUE; case PGUP: case PGDN: rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2); PostMessage(wnd, LB_SELECTION, wnd->wtop, FALSE); return rtn; case HOME: rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2); PostMessage(wnd, LB_SELECTION, 0, FALSE); return rtn; case END: rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2); PostMessage(wnd, LB_SELECTION, wnd->wlines-1, FALSE); return rtn; case '\r': if (wnd->selection != -1) { WINDOW pwnd = GetParent(wnd); int sel = wnd->selection; SendMessage(wnd, LB_SELECTION, sel, TRUE); SendMessage(pwnd, LB_CHOOSE, sel, 0); } return TRUE; default: break; } break; case BUTTON_RELEASED: py = -1; break; case LEFT_BUTTON: if (!(WindowMoving || WindowSizing)) { RECT rc = ClientRect(wnd); if (!InsideRect(p1, p2, rc)) break; if (my != py) { int newsel = wnd->wtop+my-1; if (*TextLine(wnd, newsel) != LINE) SendMessage(wnd, LB_SELECTION, newsel, TRUE); py = my; } return TRUE; } break; case DOUBLE_CLICK: BaseWndProc(LISTBOX, wnd, msg, p1, p2); if (!(WindowMoving || WindowSizing)) SendMessage(GetParent(wnd), LB_CHOOSE, wnd->selection, 0); return TRUE; case LB_SETSELECTION: change_selection(wnd, (int) p1); return TRUE; case LB_SELECTION: { WINDOW pwnd = GetParent(wnd); CLASS class = GetClass(pwnd); change_selection(wnd, (int) p1); if (class != LISTBOX && DerivedClass(class) != LISTBOX) SendMessage(GetParent(wnd), LB_SELECTION, wnd->selection, 0); return TRUE; } case LB_CURRENTSELECTION: return wnd->selection; case LB_GETTEXT: if ((int)p2 != -1) { char *cp1 = (char *)p1; char *cp2 = TextLine(wnd, (int)p2); while (cp2 && *cp2 && *cp2 != '\n') *cp1++ = *cp2++; *cp1 = '\0'; } return TRUE; case PAINT: if (isVisible(wnd)) { rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2); writeselection(wnd, wnd->selection, TRUE, (RECT *)p1); return rtn; } break; default: break; } return BaseWndProc(LISTBOX, wnd, msg, p1, p2); } static int near selection_in_window(WINDOW wnd, int sel) { return (wnd->wlines && sel >= wnd->wtop && sel < wnd->wtop+ClientHeight(wnd)); } static void near writeselection(WINDOW wnd, int sel, int reverse, RECT *rc) { if (selection_in_window(wnd, sel)) WriteTextLine(wnd, rc, sel-wnd->wtop, reverse); } static void near change_selection(WINDOW wnd, int sel) { if (sel != wnd->selection) { writeselection(wnd, wnd->selection, FALSE, NULL); wnd->selection = sel; writeselection(wnd, sel, TRUE, NULL); } }