void DropDownList::show(bool in_place, wxPoint pos, RealRect* rect) {
    if (IsShown()) return;
    onShow();
    // find selection
    selected_item = selection();
    // width
    size_t count = itemCount();
    if (item_size.width == 100) { // not initialized
        wxClientDC dc(this);
        dc.SetFont(*wxNORMAL_FONT);
        for (size_t i = 0 ; i < count ; ++i) {
            int text_width;
            dc.GetTextExtent(capitalize(itemText(i)), &text_width, 0);
            item_size.width = max(item_size.width, text_width + icon_size.width + 14); // 14 = room for popup arrow + padding
        }
    }
    // height
    int line_count = 0;
    for (size_t i = 0 ; i < count ; ++i) if (lineBelow(i)) line_count += 1;
    // size
    RealSize border_size(2,2); // GetClientSize() - GetSize(), assume 1px borders
    RealSize size(
        item_size.width + marginW * 2,
        item_size.height * count + marginH * 2 + line_count
    );
    // placement
    int parent_height = 0;
    if (!in_place && viewer) {
        // Position the drop down list below the editor control (based on the style)
        Rotation rot = viewer->viewer.getRotation();
        Rotater rr(rot, viewer->getRotation());
        RealRect r = rot.trRectToBB(rect ? *rect : rot.getInternalRect());
        if (viewer->viewer.nativeLook()) {
            pos           = RealPoint(r.x - 3, r.y - 3);
            size.width    = max(size.width, r.width + 6);
            parent_height = (int)r.height + 6;
        } else {
            pos           = RealPoint(r.x - 1, r.y - 1);
            parent_height = (int)r.height;
        }
    } else if (parent_menu) {
        parent_height = -(int)item_size.height - 1;
    }
    pos = GetParent()->ClientToScreen(pos);
    // virtual size = item size
    RealSize virtual_size = size;
    SetVirtualSize(virtual_size);
    item_size.width = virtual_size.width - marginW * 2;
    // is there enough room for all items, or do we need a scrollbar?
    int room_below = wxGetDisplaySize().y - border_size.height - pos.y - parent_height - 50;
    int max_height = max(300, room_below);
    if (size.height > max_height) {
        size.height = max_height;
        size.width += wxSystemSettings::GetMetric(wxSYS_VSCROLL_ARROW_X); // width of scrollbar
        SetScrollbar(wxVERTICAL, 0, size.height, virtual_size.height, false);
    } else {
        SetScrollbar(wxVERTICAL,0,0,0,false);
    }
    // move & resize
    SetSize(add_diagonal(size, border_size));
    Position(pos, wxSize(0, parent_height));
    // visible item
    visible_start = 0;
    ensureSelectedItemVisible();
    // set event handler
    if (hider) {
        assert(hider2);
        wxGetTopLevelParent(GetParent())->PushEventHandler(hider);
        GetParent()                     ->PushEventHandler(hider2);
    }
    // show
    if (selected_item == NO_SELECTION && itemCount() > 0) selected_item = 0; // select first item by default
    mouse_down = false;
    close_on_mouse_out = false;
    wxPopupWindow::Show();
    if (isRoot() && GetParent()->HasCapture()) {
        // release capture on parent
        GetParent()->ReleaseMouse();
    }
    // fix drop down arrow
    redrawArrowOnParent();
}