void DropDownList::OnShowPopup() { // Resize the popup to match the size of the list content, and optionally match the button width UIElement* content = listView_->GetContentElement(); content->UpdateLayout(); const IntVector2& contentSize = content->GetSize(); const IntRect& border = popup_->GetLayoutBorder(); popup_->SetSize(resizePopup_ ? GetWidth() : contentSize.x_ + border.left_ + border.right_, contentSize.y_ + border.top_ + border.bottom_); // Check if popup fits below the button. If not, show above instead bool showAbove = false; UIElement* root = GetRoot(); if (root) { const IntVector2& screenPos = GetScreenPosition(); if (screenPos.y_ + GetHeight() + popup_->GetHeight() > root->GetHeight() && screenPos.y_ - popup_->GetHeight() >= 0) showAbove = true; } SetPopupOffset(0, showAbove ? -popup_->GetHeight() : GetHeight()); }
void ListView::OnKey(int key, int buttons, int qualifiers) { // If no selection, can not move with keys unsigned numItems = GetNumItems(); unsigned selection = GetSelection(); // If either shift or ctrl held down, add to selection if multiselect enabled bool additive = multiselect_ && qualifiers & (QUAL_SHIFT | QUAL_CTRL); int delta = M_MAX_INT; int pageDirection = 1; if (numItems) { if (selection != M_MAX_UNSIGNED && qualifiers & QUAL_CTRL && key == KEY_C) { CopySelectedItemsToClipboard(); return; } switch (key) { case KEY_LEFT: case KEY_RIGHT: if (selection != M_MAX_UNSIGNED && hierarchyMode_) { Expand(selection, key == KEY_RIGHT); return; } break; case KEY_RETURN: case KEY_RETURN2: case KEY_KP_ENTER: if (selection != M_MAX_UNSIGNED && hierarchyMode_) { ToggleExpand(selection); return; } break; case KEY_UP: delta = -1; break; case KEY_DOWN: delta = 1; break; case KEY_PAGEUP: pageDirection = -1; // Fallthru case KEY_PAGEDOWN: { // Convert page step to pixels and see how many items have to be skipped to reach that many pixels if (selection == M_MAX_UNSIGNED) selection = 0; // Assume as if first item is selected int stepPixels = ((int)(pageStep_ * scrollPanel_->GetHeight())) - contentElement_->GetChild(selection)->GetHeight(); unsigned newSelection = selection; unsigned okSelection = selection; unsigned invisible = 0; while (newSelection < numItems) { UIElement* item = GetItem(newSelection); int height = 0; if (item->IsVisible()) { height = item->GetHeight(); okSelection = newSelection; } else ++invisible; if (stepPixels < height) break; stepPixels -= height; newSelection += pageDirection; } delta = okSelection - selection - pageDirection * invisible; } break; case KEY_HOME: delta = -(int)GetNumItems(); break; case KEY_END: delta = GetNumItems(); break; default: break; } } if (delta != M_MAX_INT) { ChangeSelection(delta, additive); return; } using namespace UnhandledKey; VariantMap& eventData = GetEventDataMap(); eventData[P_ELEMENT] = this; eventData[P_KEY] = key; eventData[P_BUTTONS] = buttons; eventData[P_QUALIFIERS] = qualifiers; SendEvent(E_UNHANDLEDKEY, eventData); }