/* --------------------------------------------------------------------- * CbDropdownVScrollHook * Scroll bar mouse hook * --------------------------------------------------------------------- */ static void CbDropdownVScrollHook(void* w, int sbcode, int pos) { CUIWINDOW* win = (CUIWINDOW*) w; CUIRECT rc; int sbpos, range; CUI_USE_ARG(pos); WindowGetClientRect(win, &rc); sbpos = WindowGetVScrollPos(win); range = WindowGetVScrollRange(win); switch(sbcode) { case SB_LINEUP: if (sbpos > 0) { WindowSetVScrollPos(win, sbpos - 1); WindowInvalidate(win); } break; case SB_LINEDOWN: if (sbpos < range) { WindowSetVScrollPos(win, sbpos + 1); WindowInvalidate(win); } break; case SB_PAGEUP: if (sbpos > 0) { sbpos -= (rc.H - 1); sbpos = (sbpos < 0) ? 0 : sbpos; WindowSetVScrollPos(win, sbpos); WindowInvalidate(win); } break; case SB_PAGEDOWN: if (sbpos < range) { sbpos += (rc.H - 1); sbpos = (sbpos > range) ? range : sbpos; WindowSetVScrollPos(win, sbpos); WindowInvalidate(win); } break; case SB_THUMBTRACK: WindowInvalidate(win); break; } }
/* --------------------------------------------------------------------- * TerminalPaintHook * Handle PAINT events by redrawing the list view control * --------------------------------------------------------------------- */ static void TerminalPaintHook(void* w) { CUIWINDOW* win = (CUIWINDOW*) w; CUIRECT rc; TERMINALDATA* data; int yscroll; int ypos; int line; data = (TERMINALDATA*) win->InstData; if (!data) return; WindowGetClientRect(win, &rc); if ((rc.W <= 0)||(rc.H <= 0)) return; yscroll = WindowGetVScrollPos(win); ypos = 0; line = (data->FirstLine + yscroll) % MAX_TERMLINES; while (line != data->YCursor) { if (ypos < rc.H) { TerminalShowLine(win, ypos, line, &rc); ypos++; } line = (line + 1) % MAX_TERMLINES; } if (ypos < rc.H) { TerminalShowLine(win, ypos, line, &rc); ypos++; } ypos = ((data->YCursor - data->FirstLine + MAX_TERMLINES) % MAX_TERMLINES) - yscroll; WindowSetCursor(win, data->XCursor, ypos); }
/* --------------------------------------------------------------------- * CbDropdownCalcPos * Recalculate Listbox position * --------------------------------------------------------------------- */ static void CbDropdownCalcPos(CUIWINDOW* win) { CUIRECT rc; COMBOBOXDATA* data = (COMBOBOXDATA*) win->InstData; int range; int pos; if (!data) return; if (win->IsCreated) { WindowGetClientRect(win, &rc); range = data->NumItems - rc.H; if (range < 0) { WindowSetVScrollRange(win, 0); WindowSetVScrollPos(win, 0); } else { WindowSetVScrollRange(win, range); pos = WindowGetVScrollPos(win); if (data->SelIndex < 0) { WindowSetVScrollPos(win, 0); } else if (data->SelIndex - pos >= rc.H) { WindowSetVScrollPos(win, data->SelIndex - rc.H + 1); } else if (data->SelIndex - pos < 0) { WindowSetVScrollPos(win, data->SelIndex); } } } }
/* --------------------------------------------------------------------- * TerminalKeyHook * Handle EVENT_KEY events * --------------------------------------------------------------------- */ static int TerminalKeyHook(void* w, int key) { CUIWINDOW* win = (CUIWINDOW*) w; TERMINALDATA* data = (TERMINALDATA*) win->InstData; CUIRECT rc; int yrange; int yscroll; if (!data) return FALSE; WindowGetClientRect(win, &rc); yscroll = WindowGetVScrollPos(win); yrange = WindowGetVScrollRange(win); if (win->IsEnabled) { /* if the key is processed by the custom callback hook, we are over and done with it, else processing continues */ if (data->PreKeyHook) { if (data->PreKeyHook(data->PreKeyTarget, win, key)) { return TRUE; } } switch(key) { case KEY_DOWN: if (yscroll < yrange) { WindowSetVScrollPos(win, yscroll + 1); WindowInvalidate(win); TerminalCursorOnOff(win); } return TRUE; case KEY_UP: if (yscroll > 0) { WindowSetVScrollPos(win, yscroll - 1); WindowInvalidate(win); TerminalCursorOnOff(win); } return TRUE; case KEY_NPAGE: if (yscroll < yrange) { yscroll += (rc.H - 1); if (yscroll > yrange) { yscroll = yrange; } WindowSetVScrollPos(win, yscroll); WindowInvalidate(win); TerminalCursorOnOff(win); } return TRUE; case KEY_PPAGE: if (yscroll > 0) { yscroll -= (rc.H - 1); if (yscroll < 0) { yscroll = 0; } WindowSetVScrollPos(win, yscroll); WindowInvalidate(win); TerminalCursorOnOff(win); } return TRUE; case KEY_HOME: if (yscroll > 0) { WindowSetVScrollPos(win, 0); WindowInvalidate(win); TerminalCursorOnOff(win); } return TRUE; case KEY_END: if (yscroll < yrange) { WindowSetVScrollPos(win, yrange); WindowInvalidate(win); TerminalCursorOnOff(win); } return TRUE; default: if (data->CoProc) { if ((key >= KEY_SPACE) && (key <= 255)) { wchar_t c = (wchar_t) key; TerminalCoWrite(data->CoProc, &c, 1); return TRUE; } else if (key == KEY_RETURN) { TerminalCoWrite(data->CoProc, _T("\n"), 1); return TRUE; } } if (data->PostKeyHook) { if (data->PostKeyHook(data->PostKeyTarget, win, key)) { return TRUE; } } } } return FALSE; }
/* --------------------------------------------------------------------- * CbDropdownPaintHook * Handle PAINT events by redrawing the control * --------------------------------------------------------------------- */ static void CbDropdownPaintHook(void* w) { CUIWINDOW* win = (CUIWINDOW*) w; CUIRECT rc; COMBOBOXDATA* data; COMBOBOXITEM* item; int pos; int cursor; int index; int len; int x,y; data = (COMBOBOXDATA*) win->InstData; if (!data) return; WindowGetClientRect(win, &rc); if ((rc.W <= 0)||(rc.H <= 0)) return; pos = WindowGetVScrollPos(win); index = 0; y = 0; cursor = 0; item = data->FirstItem; while(item) { if ((index >= pos) && (index < pos + rc.H)) { len = wcslen(item->ItemText); if (index == data->SelIndex) { SetColor(win->Win, win->Color.SelTxtColor, win->Color.WndSelColor, TRUE); cursor = y; } else { if (win->IsEnabled) { SetColor(win->Win, win->Color.WndTxtColor, win->Color.WndColor, FALSE); } else { SetColor(win->Win, win->Color.InactTxtColor, win->Color.WndColor, FALSE); } } MOVEYX(win->Win, y, 0); for (x = 0; x < rc.W; x++) { if ((x > 0) && (x <= len)) { PRINTN(win->Win, &item->ItemText[x - 1], 1); } else { PRINT(win->Win, _T(" ")); } } y ++; } else if (index >= pos + rc.H) { break; } index++; item = (COMBOBOXITEM*) item->Next; } WindowSetCursor(win, 0, cursor); }
/* --------------------------------------------------------------------- * CbDropdownMButtonHook * Button mouse click hook * --------------------------------------------------------------------- */ static void CbDropdownMButtonHook(void* w, int x, int y, int flags) { CUIWINDOW* win = (CUIWINDOW*) w; COMBOBOXDATA* data = (COMBOBOXDATA*) win->InstData; if ((flags & BUTTON1_CLICKED) || (flags & BUTTON1_DOUBLE_CLICKED)) { int offsy = WindowGetVScrollPos(win); int nochange = FALSE; y += offsy; WindowReleaseCapture(); if ((y != data->SelIndex) && (y < data->NumItems)) { if (CbDropdownQueryChange(win, data)) { data->SelIndex = y; CbDropdownUpdate(win); CbDropdownNotifyChange(win, data); } else { nochange = TRUE; } } /* only execute clicked hook, if change was not rejected by the application */ if (!nochange) { if (data->SelIndex != data->CtrlSelIndex) { if (ComboboxQueryChange(data->Ctrl, data)) { data->CtrlSelIndex = data->SelIndex; ComboboxNotifyChange(data->Ctrl, data); } } data->CloseKey = KEY_SPACE; WindowClose(win, IDOK); } } else if (flags & BUTTON1_PRESSED) { data->MouseDown = TRUE; WindowSetCapture(win); } else if ((flags & BUTTON1_RELEASED) && (data->MouseDown)) { CUIRECT rc; int nochange = FALSE; WindowGetClientRect(win, &rc); data->MouseDown = FALSE; WindowReleaseCapture(); if ((x >= rc.X) && (x < (rc.X + rc.W)) && (y >= rc.Y) && (y < (rc.Y + rc.H))) { int offsy = WindowGetVScrollPos(win); y += offsy; if ((y != data->SelIndex) && (y < data->NumItems)) { CbDropdownQueryChange(win, data); data->SelIndex = y; CbDropdownUpdate(win); CbDropdownNotifyChange(win, data); } else { nochange = TRUE; } } if (!nochange) { if (data->SelIndex != data->CtrlSelIndex) { if (ComboboxQueryChange(data->Ctrl, data)) { data->CtrlSelIndex = data->SelIndex; ComboboxNotifyChange(data->Ctrl, data); } } data->CloseKey = KEY_SPACE; WindowClose(win, IDOK); } } }
/* --------------------------------------------------------------------- * ListboxMButtonHook * Button mouse click hook * --------------------------------------------------------------------- */ static void ListboxMButtonHook(void* w, int x, int y, int flags) { CUIWINDOW* win = (CUIWINDOW*) w; LISTBOXDATA* data = (LISTBOXDATA*) win->InstData; if ((flags & BUTTON1_CLICKED) || (flags & BUTTON1_DOUBLE_CLICKED)) { int offsy = WindowGetVScrollPos(win); int nochange = FALSE; y += offsy; WindowReleaseCapture(); if ((y != data->SelIndex) && (y < data->NumItems)) { if (ListboxQueryChange(win, data)) { data->SelIndex = y; ListboxUpdate(win); ListboxNotifyChange(win, data); } else { nochange = TRUE; } } /* only execute clicked hook, if change was not rejected by the application */ if (!nochange) { if ((flags & BUTTON1_DOUBLE_CLICKED) && (data->LbClickedHook)) { data->LbClickedHook(data->LbClickedTarget, win); } } } else if (flags & BUTTON1_PRESSED) { data->MouseDown = TRUE; WindowSetCapture(win); } else if ((flags & BUTTON1_RELEASED) && (data->MouseDown)) { CUIRECT rc; WindowGetClientRect(win, &rc); data->MouseDown = FALSE; WindowReleaseCapture(); if ((x >= rc.X) && (x < (rc.X + rc.W)) && (y >= rc.Y) && (y < (rc.Y + rc.H))) { int offsy = WindowGetVScrollPos(win); y += offsy; if ((y != data->SelIndex) && (y < data->NumItems)) { ListboxQueryChange(win, data); data->SelIndex = y; ListboxUpdate(win); ListboxNotifyChange(win, data); } } } }