Reordering sibling windows

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.
Antipole
Knows some wx things
Knows some wx things
Posts: 45
Joined: Thu May 28, 2020 5:38 pm

Reordering sibling windows

Post by Antipole »

I have an application that creates a number of consoles, these being wxDialog windows, which are all children of the same parent frame and siblings to each other.
I create consoles One, Two, and Three - all partially overlapping, so One is overlapped by Two which is overlapped by Three - this last being the front one.
When I click on One or Two, it gains focus and becomes the active window as expected. But it remains partially obscured by the later-created windows. I have tried processing the wxActivateEvent thus:

Code: Select all

void Console::OnActivate(  wxActivateEvent& event ){
    if (!isActiveWindow){
        TRACE(4, wxString::Format(_("Activatating %s for reason %d"), mConsoleName, event.GetActivationReason()));
        Raise();
        isActiveWindow = true;
        RequestRefresh(m_parent);
        }
    else {
        TRACE(4, wxString::Format(_("Deactivatating %s for reason %d"), mConsoleName,
            event.GetActivationReason()));
        Lower();
        isActiveWindow = false;
        }
    }
The trace shows that this is called once for the console losing focus and then once for the console gaining focus - always with reason 1. HasFocus() always seems to be true, so I have a console attribute isActiveWindow so I know which is the currently active window. The trace shows that I am calling Lower() on the console losing focus and Raise() on the console gaining focus. But the overlap order remains unchanged with the active console partially obscured by later ones.
Please can SKS enlighten me on how to make the active console become the front-most?
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7479
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Reordering sibling windows

Post by ONEEYEMAN »

Hi,
what OS and wxWidgets version?
How did you create those windows? Can you show some code?

Thank you.
Antipole
Knows some wx things
Knows some wx things
Posts: 45
Joined: Thu May 28, 2020 5:38 pm

Re: Reordering sibling windows

Post by Antipole »

MacOS 10.15.7
wxWidgets version 3.1.2.0 ( I cannot use a later version for compatibility reasons)

Console base class m_console is generated with wxFormBuilder
My Console derived class adds attributes and methods and I construct with

Code: Select all

    Console(wxWindow *parent, wxString consoleName, wxPoint consolePosition = wxPoint(300,20), wxPoint dialogPosition = wxPoint(100, 100), wxPoint alertPosition = wxPoint(50, -1), wxString fileString = wxEmptyString, bool autoRun = false): m_Console(parent, wxID_ANY, consoleName, consolePosition, wxDefaultSize, wxCAPTION|wxRESIZE_BORDER|wxCLOSE_BOX|wxMINIMIZE|wxSYSTEM_MENU)
and then create a console instance with

Code: Select all

pConsole = new Console(pJavaScript_pi->m_parent_window, newConsoleName);
I hope that helps
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7479
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Reordering sibling windows

Post by ONEEYEMAN »

Hi,
So they are basically wxWindow objects?

Thank you.
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Reordering sibling windows

Post by doublemax »

I have an application that creates a number of consoles, these being wxDialog windows, which are all children of the same parent frame and siblings to each other.
As you have multiple wxDialogs, i assume they're all non-modal? That doesn't sound like a good idea. Turn them all into wxFrames and i guess your problems go away.
Use the source, Luke!
Antipole
Knows some wx things
Knows some wx things
Posts: 45
Joined: Thu May 28, 2020 5:38 pm

Re: Reordering sibling windows

Post by Antipole »

Indeed they are non-modal.

This is a JavaScript plugin for OpenCPN - a marine navigation program. A brief description of the plugin is here. I cannot use modal windows because the consoles are open for extended periods - could be months - and it would hold up the functioning of the main program. Scripts often set up call-backs to JavaScript functions which are called when the relevant event in OpenCPN occurs. Example JavaScript:

Code: Select all

OPCNonNMEAsentence(received);

function received(sentence) {
       if (sentence.OK) print("NMEA checksum OK and data is ", sentence.value, "\n");
      OPCNonNMEAsentence(received);
      }
Here the first line sets up a call-back. When an NMEA sentence is received by OpenCPN, it is passed as a structure to the function received, which then sets up a callback for the next sentence. Such a script may be running indefinitely.

My new multi-console version is working well and allows multiple scripts to run independently and pseudo concurrently. The only problem I have is this issue of overlapping consoles.
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Reordering sibling windows

Post by doublemax »

Indeed they are non-modal.
Then why are they dialogs? Switching the base class to wxFrame should be easy to do, just try it and check if it solves the issue.
Use the source, Luke!
Antipole
Knows some wx things
Knows some wx things
Posts: 45
Joined: Thu May 28, 2020 5:38 pm

Re: Reordering sibling windows

Post by Antipole »

They were wxDialog because when I commenced this project I did not know wxWidgets nor C++. I started with an example plugin that uses wxDialog.

I have now switched to wxFrame and all is working fine as wished, with no need to process any events.

wxFormBuilder has no capability to change the window type (at least my version does not). But its .fpb save file is XML and it contained just one occurrence of the text wxDialog and one of wxDEFAULT_DIALOG_STYLE. I edited them to be wxFrame and wxDEFAULT_FRAME_STYLE. It opened OK in wxFormBuilder and I regenerated the C++ code and that was it :D

Many thanks for the help - expecially doublemax.
Antipole
Knows some wx things
Knows some wx things
Posts: 45
Joined: Thu May 28, 2020 5:38 pm

Re: Reordering sibling windows

Post by Antipole »

Whoops... now I have installed the plugin into its host application, a major problem.

OpenCPN displays its main window containing the navigational chart. My plugin was displaying its wxDialog window on top of this.

Since I switched to wxFrame, clicking anywhere on the main window brings that over the top of my console, which is now behind but still listed in the windows menu. I need my console windows to stay on top of the OpenCPN window.
NB when creating a console I give the OpenCPN window as the parent.

So, to clarify - I need to keep all my consoles on top of the main OpenCPN window even when clicking on that window (as happened with wxDialog) and find a way of keeping the active console on top of the other consoles. Any suggestions, please?
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4204
Joined: Sun Jan 03, 2010 5:45 pm

Re: Reordering sibling windows

Post by PB »

Did you create your frames with a style including wxFRAME_FLOAT_ON_PARENT?
Antipole
Knows some wx things
Knows some wx things
Posts: 45
Joined: Thu May 28, 2020 5:38 pm

Re: Reordering sibling windows

Post by Antipole »

Alas, wxFRAME_FLOAT_ON_PARENT does not help.

I have had to go back to using wxDialog.

I have now discovered that if I Hide( ) and then Show( ) a wxDialog, this brings that wxDialog on top of the other wxDialog ones.

So I tried this:

Code: Select all

void Console::OnMouse(wxMouseEvent& event){
    cout << "Moused\n";
    wxDialog* console = wxDynamicCast(event.GetEventObject(), wxDialog);
    console->Hide();
    console->Show();
    };
I am not seeing the trace, so mouse events are not arriving. I am not sure how to get that working. I understand getting a mouse event to propagate upwards is tricky?
Also, I am guessing at how to get the dialog from a mouse event if it did arrive.

Any further help will be much appreciated.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7479
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Reordering sibling windows

Post by ONEEYEMAN »

Hi,
Did you pass this into the constructor or you tried to change the frame style?

Thank you.
Antipole
Knows some wx things
Knows some wx things
Posts: 45
Joined: Thu May 28, 2020 5:38 pm

Re: Reordering sibling windows

Post by Antipole »

Sorry - not sure of your question. I am using wxFormBuilder, which generates the constructors.

If I set wxFormBuilder to send a wxActivateEvent from the wxDialog, I get that OK

Code: Select all

void Console::OnActivate(wxActivateEvent& event){
    if (event.GetActive()) {
        cout << "Activated\n";
        wxDialog* dialog = wxDynamicCast(event.GetEventObject(), wxDialog);
        dialog->Hide();
        dialog->Show();
        }
    };
But this loops perpetually because, I think, the Show( ) triggers another wxActivate
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4204
Joined: Sun Jan 03, 2010 5:45 pm

Re: Reordering sibling windows

Post by PB »

FWIW, this code does (wxWidgets master, Windows 10) what I think you wanted, i.e., frames titled "OnTop 1" and "OnTop 2" stay on top of their parent, frame titled "MAIN FRAME":

Code: Select all

#include <wx/wx.h>

class MyFrame : public wxFrame
{
public:
    MyFrame(wxWindow* parent, const wxString& title, bool stayOnTop)
        : wxFrame(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize,
                  stayOnTop ? wxDEFAULT_FRAME_STYLE | wxFRAME_FLOAT_ON_PARENT : wxDEFAULT_FRAME_STYLE)
    {
        new wxTextCtrl(this, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
        Show();
    }
};

class MyApp : public wxApp
{
public:
    bool OnInit() override
    {
        MyFrame* mainFrame = new MyFrame(nullptr, "MAIN FRAME", false);

        new MyFrame(mainFrame, "OnTop 1", true);
        new MyFrame(mainFrame, "OnTop 2", true);

        return true;
    }
}; wxIMPLEMENT_APP(MyApp);
So either I misunderstood what what you wanted or it works only on MSW or your application is somewhat different.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7479
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Reordering sibling windows

Post by ONEEYEMAN »

Hi,
I think OP wants to have 3 frames and when you click frame 1 - it become the top one (raised), and then if you click frame 2, frame 1 becomes lowered and frame 2 become raised.

So its not necessary all 3 should be staying on top.
But (s)he will definitely won't achieve this with wxDialog.

Thank you.
Post Reply