ComboCtrl and ComboPopup focuses can't set at the same time

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
nandi_shan
Knows some wx things
Knows some wx things
Posts: 47
Joined: Tue Dec 26, 2023 1:44 am

Re: ComboCtrl and ComboPopup focuses can't set at the same time

Post by nandi_shan »

Hi Doublemax,

Did you get some time to look into the query?


Regards,
nandi_shan
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: ComboCtrl and ComboPopup focuses can't set at the same time

Post by doublemax »

nandi_shan wrote: Mon Mar 25, 2024 4:29 pm Did you get some time to look into the query?
I don't have much more to add. I still believe you can achieve what you want based on the example in the "combo" sample:
https://github.com/wxWidgets/wxWidgets/ ... o.cpp#L513

Instead of opening a wxFileDialog when clicking the dropdown button, open a wxPopupWindow that is completely under your control. Other than a wxPopupTransientWindow, it will not close when it loses focus.
Use the source, Luke!
nandi_shan
Knows some wx things
Knows some wx things
Posts: 47
Joined: Tue Dec 26, 2023 1:44 am

Re: ComboCtrl and ComboPopup focuses can't set at the same time

Post by nandi_shan »

Hi Doublemax,

Instead of opening wxFileDialog, I will use wxPopupWindow and I will see whether I can able to achieve the behaviour. Thank you so much for your time and suggestions.

Regards,
nandi_shan
nandi_shan
Knows some wx things
Knows some wx things
Posts: 47
Joined: Tue Dec 26, 2023 1:44 am

Re: ComboCtrl and ComboPopup focuses can't set at the same time

Post by nandi_shan »

Hi Doublemax,

As you suggested, I have used wxpopupwindow and can able to type text seemlessly and based upon the entered text match able to show the popup elements accordingly. But the problem is, How to dynamically adjust the position of the window (w.r.t. comboctrl) and size (based on size of items added) of the popup window in accordance with wxComboCtrl? If you have any pointers, Can you point me to that? I want to achieve the popup similar to wxComboPopUp using wxpopupwindow. I have searched in wxWidgets forum but couldn't able to find exact pointers which solve my problem.

Regards,
nandi_shan
Attachments
latest.png
latest.png (11.78 KiB) Viewed 4862 times
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: ComboCtrl and ComboPopup focuses can't set at the same time

Post by doublemax »

You can change the size and position of the popup window at any time using SetSize(x, y, w, h). The coordinates are relative to the parent window, or screen coordinates if there is no parent. So, depending on what the parents of the ComboCtrl and the wxpopupwindow are, you may have to convert the coordinates for the popup window using wxWindow::ClientToScreen() and ScreenToClient().
Use the source, Luke!
nandi_shan
Knows some wx things
Knows some wx things
Posts: 47
Joined: Tue Dec 26, 2023 1:44 am

Re: ComboCtrl and ComboPopup focuses can't set at the same time

Post by nandi_shan »

Hi Doublemax,

Sure, I will try. Thank you.

Regards,
nandi_shan
nandi_shan
Knows some wx things
Knows some wx things
Posts: 47
Joined: Tue Dec 26, 2023 1:44 am

Re: ComboCtrl and ComboPopup focuses can't set at the same time

Post by nandi_shan »

Hi Doublemax,

Is there any way to close wxpopupwindow? I can able to show the window using Show() but can't able to close the wxpopupwindow. I have tried Show(false), Close(), Destroy(). But none of them worked. Can you suggest any way to close wxpopupwindow?


Regards,
nandi_shan
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: ComboCtrl and ComboPopup focuses can't set at the same time

Post by doublemax »

nandi_shan wrote: Tue Apr 02, 2024 6:53 am Is there any way to close wxpopupwindow? I can able to show the window using Show() but can't able to close the wxpopupwindow. I have tried Show(false), Close(), Destroy(). But none of them worked. Can you suggest any way to close wxpopupwindow?
As wxPopupWindow is still a wxWindow, any of those should have worked. What happens, does it just remain on screen?
Use the source, Luke!
nandi_shan
Knows some wx things
Knows some wx things
Posts: 47
Joined: Tue Dec 26, 2023 1:44 am

Re: ComboCtrl and ComboPopup focuses can't set at the same time

Post by nandi_shan »

Hi Doublemax,

Yes, it remains on the screen.

Regards,
nandi_shan
nandi_shan
Knows some wx things
Knows some wx things
Posts: 47
Joined: Tue Dec 26, 2023 1:44 am

Re: ComboCtrl and ComboPopup focuses can't set at the same time

Post by nandi_shan »

Hi Doublemax,

One observation: As soon as Show() is called the very next line I have called Show(false). In that case popup is not shown. But once the popup is shown and try to close it some other place then cannot able to close it using any on the methods (Show(), Close(), Destroy()).

Regards,
nandi_shan
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: ComboCtrl and ComboPopup focuses can't set at the same time

Post by doublemax »

I have no explanation for this. Can you show some code in context?
Use the source, Luke!
nandi_shan
Knows some wx things
Knows some wx things
Posts: 47
Joined: Tue Dec 26, 2023 1:44 am

Re: ComboCtrl and ComboPopup focuses can't set at the same time

Post by nandi_shan »

Code: Select all

#include <wx/wx.h>
#include "wx/combo.h"
#include "wx/popupwin.h"
#include <wx/listctrl.h>
#include <vector>

class MyPopupWindow : public wxPopupWindow {
public:
    MyPopupWindow(wxWindow* parent) : wxPopupWindow() {
        // Create the popup window
        Create(parent, wxBORDER_DEFAULT);
        SetSize(wxSize(475, 25)); // Set your desired size here
        SetPosition(wxPoint(12, 12));
        SetSize(115, 160, 400, 400);
    }
    void SetListOfItemsToShow(wxComboCtrl* comboctrl, std::vector<wxString> items)
    {
        m_comboCtrl = comboctrl;
        int* w = nullptr;
        int* h = nullptr;
        comboctrl->GetSize(w, h);
        auto res = comboctrl->GetPosition();
        // Create a list view control with one column
        auto res1 = comboctrl->GetClientSize();
        m_listView = new wxListView(this, wxID_ANY, wxPoint(10, 10), wxSize(300, 400), wxLC_SINGLE_SEL | wxLC_LIST);

        wxPoint comboScreenPos = ClientToScreen(wxPoint(0, 0));
        // Get the size of the combo control
        wxSize comboSize = GetParent()->GetSize();

        // Calculate the position for the custom list view
        wxPoint listViewPos(comboScreenPos.x, comboScreenPos.y + comboSize.y);

        m_listView->SetPosition(listViewPos);

        // Assuming listView is your wxListView instance
        m_listView->Bind(wxEVT_LIST_ITEM_SELECTED, &MyPopupWindow::OnItemSelected, this);

        // Add items to the list view
        m_listView->ClearAll();

        for (int i = 0; i < items.size(); ++i) {
            m_listView->InsertItem(i, items.at(i));
        }

        // Set up sizer
        wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
        sizer->Add(m_listView, 1, wxEXPAND | wxALL, 5);
        SetSizerAndFit(sizer);

        comboctrl->Refresh();
        m_listView->Refresh();

    }
    // Event handler for item selection
    void OnItemSelected(wxListEvent& event)
    {
        // Retrieve the index of the selected item
        long index = event.GetIndex();

        // Get the selected item text
        wxString selectedItemText = m_listView->GetItemText(index);

        // Update the text control with the selected item text
        m_comboCtrl->SetValue(selectedItemText);
        m_comboCtrl->SetInsertionPointEnd();
    }
private:
    wxComboCtrl* m_comboCtrl = nullptr;
    wxListView* m_listView = nullptr;
};


class MyComboCtrl : public wxComboCtrl
{
public:
    MyComboCtrl() : wxComboCtrl() { Init(); }

    MyComboCtrl(wxWindow* parent,
        wxWindowID id = wxID_ANY,
        const wxString& value = wxEmptyString,
        const wxPoint& pos = wxDefaultPosition,
        const wxSize& size = wxDefaultSize,
        long style = 0,
        const wxValidator& validator = wxDefaultValidator,
        const wxString& name = wxComboBoxNameStr)
        : wxComboCtrl()
    {
        Init();
        Create(parent, id, value,
            pos, size,
            // Style flag wxCC_STD_BUTTON makes the button
            // behave more like a standard push button.
            style | wxCC_STD_BUTTON,
            validator, name);
    }

    virtual void OnButtonClick() override
    {

    }

    // Implement empty DoSetPopupControl to prevent assertion failure.
    virtual void DoSetPopupControl(wxComboPopup* WXUNUSED(popup)) override
    {
    }
    virtual void HidePopup(bool generateEvent = false)
    {

    }
    void OnTextChanged(wxCommandEvent& event, std::vector<wxString> items, bool customlogic)
    {
        if (!customlogic)
        {
            std::vector<wxString> updatedItemList;

            //Create a new instance of MyPopupWindow at a position below this popup window
            MyPopupWindow* newPopup = new MyPopupWindow(this);

            updatedItemList.empty();
            wxComboCtrl* comboCtrl = dynamic_cast<wxComboCtrl*>(event.GetEventObject());
            wxString searchItem = comboCtrl->GetValue();
            for (auto& item : items) {
                wxString itemL = item.Lower();
                wxString searchItemL = searchItem.Lower();
                if (itemL.Contains(searchItemL)) {
                    updatedItemList.emplace_back(item);
                }
            }
            items.clear();
            if (!updatedItemList.empty())
            {
                newPopup->SetListOfItemsToShow(comboCtrl, updatedItemList);
                newPopup->Show(true);
                newPopup->Refresh();
            }
            else {
                newPopup->SetListOfItemsToShow(comboCtrl, updatedItemList);
                newPopup->Show(false);
                newPopup->Refresh();
            }
        }
        else
        {
            //customLogic here
        }
    }

private:
    void Init()
    {
        // Initialize member variables here
    }
};


class MyApp : public wxApp
{
public:
    virtual bool OnInit() override
    {
        wxFrame* frame = new wxFrame(nullptr, wxID_ANY, "My App", wxPoint(125, 125), wxSize(550, 460));
        wxPanel* panel = new wxPanel(frame);

        std::vector<wxString> items;
        items.push_back("Items 1");
        items.push_back("Items 2");
        items.push_back("Items 3");
        items.push_back("Items 4");
        items.push_back("Items 5");
        items.push_back("Items 6");
        items.push_back("Items 7");
        items.push_back("Items 8");

        MyComboCtrl* myComboCtrl = new MyComboCtrl(panel, wxID_ANY, wxEmptyString,
            wxPoint(10, 10), wxSize(475, 25),
            (long)0);

        // Bind the text change event to a lambda function
        myComboCtrl->Bind(wxEVT_TEXT, [=](wxCommandEvent& event) {
            myComboCtrl->OnTextChanged(event, items, false);
            });

        frame->Show();
        return true;
    }
};

wxIMPLEMENT_APP(MyApp);

Hi Doublemax,

PFA the sample code. Try typing any character in string ("Items") or any numbers till 8. The pop will be shown. Now try to type 'z' since there is no character. The popup should hide. But it is not happening. Also, please suggest if any other improvements are needed.

Regards,
nandi_shan
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: ComboCtrl and ComboPopup focuses can't set at the same time

Post by doublemax »

Code: Select all

MyPopupWindow* newPopup = new MyPopupWindow(this);
Why are you creating a new popup every time?

Let's suppose i press 'A', then you create the popup window and show it. But this instance will never get destroyed.
Use the source, Luke!
nandi_shan
Knows some wx things
Knows some wx things
Posts: 47
Joined: Tue Dec 26, 2023 1:44 am

Re: ComboCtrl and ComboPopup focuses can't set at the same time

Post by nandi_shan »

Hi Doublemax,

Sorry, I overlooked it. Will check. Thanks.


Regards,
nandi_shan
Post Reply