/* --------------------------------------------------------------------- * ComboboxMButtonHook * Button mouse click hook * --------------------------------------------------------------------- */ static void ComboboxMButtonHook(void* w, int x, int y, int flags) { CUIWINDOW* win = (CUIWINDOW*) w; COMBOBOXDATA* data = (COMBOBOXDATA*) win->InstData; CUI_USE_ARG(x); CUI_USE_ARG(y); if ((flags & BUTTON1_CLICKED) || (flags & BUTTON1_DOUBLE_CLICKED)) { ComboboxShowDropdown(win, data, FALSE); } else if (flags & BUTTON1_PRESSED) { ComboboxShowDropdown(win, data, TRUE); } else if ((flags & BUTTON1_RELEASED) && (data->MouseDown)) { WindowReleaseCapture(); } }
/* --------------------------------------------------------------------- * ComboboxShowDropdown * Display dropdown window * --------------------------------------------------------------------- */ static void ComboboxShowDropdown(CUIWINDOW* win, COMBOBOXDATA* data, int capture) { CUIWINDOW* listbox; CUIRECT rc; int height; WindowGetWindowRect(win, &rc); height = ((data->NumItems + 2) > data->Height) ? data->Height : (data->NumItems + 2); if ((LINES - rc.Y) > height) { listbox = WindowNew(win, rc.X, rc.Y + 1, rc.W, height, CWS_POPUP | CWS_BORDER | CWS_TABSTOP); } else if (rc.Y > (LINES / 2)) { if (height > (rc.Y - 1)) { height = rc.Y - 1; } listbox = WindowNew(win, rc.X, rc.Y - height - 1, rc.W, height, CWS_POPUP | CWS_BORDER | CWS_TABSTOP); } else { if (height > (LINES - rc.Y - 1)) { height = LINES - rc.Y - 1; } listbox = WindowNew(win, rc.X, rc.Y + 1, rc.W, height, CWS_POPUP | CWS_BORDER | CWS_TABSTOP); } listbox->Class = _T("CBDROPDOWN"); WindowSetPaintHook(listbox, CbDropdownPaintHook); WindowSetKeyHook(listbox, CbDropdownKeyHook); WindowSetMButtonHook(listbox, CbDropdownMButtonHook); WindowSetVScrollHook(listbox, CbDropdownVScrollHook); WindowSetSizeHook(listbox, CbDropdownSizeHook); WindowSetSetFocusHook(listbox, CbDropdownSetFocusHook); WindowSetKillFocusHook(listbox, CbDropdownKillFocusHook); WindowEnableVScroll(listbox, TRUE); listbox->InstData = (void*) data; data->SelIndex = data->CtrlSelIndex; data->MouseDown = capture; data->DropdownState = TRUE; data->CloseKey = 0; if (height > 0) { WindowCreate(listbox); if (capture) { WindowSetCapture(listbox); } WindowModal(listbox); WindowReleaseCapture(); } WindowDestroy(listbox); data->DropdownState = FALSE; ComboboxUpdate(win); switch(data->CloseKey) { case KEY_TAB: case KEY_RIGHT: WindowFocusNext(win->Parent); break; case KEY_LEFT: WindowFocusPrevious(win->Parent); break; } }
/* --------------------------------------------------------------------- * 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); } } } }