Dear all,

I am using plplot 5.13.0 and wxwidgets 3.1.0 in a windows environment, VS 2017. I've attempted to merge the plplot wxwidgets example with more complex wxwidgets examples to generate plots in various frames and panels in a larger GUI format.

The specific example that produced the figures in this email were made using wxWidgets uiaction sample (UI action simulator) and the WxPLplotDemo code.

In a nut shell I've made a splitter window in the main GUI and placed a copy of one of the plots there via a call to Plot() in the mainframe definition. The same plot is called for some menu action too.

The issue I am seeing is that the plot in the main GUI does not have axis labels or tick mark values but the separate plot, activated by the menu does.

Also, if I refresh the plot in the gui via a separate menu action the missing data returns.

All calls are to the same function. I'm asking here first since it's the plot generated by PLplot that is inconsistency but it may be a wxwidgets issue.

(it is clear that I was messing with other PLplot attributes too, like subplot, color, etc. This was not the cause of the difference as it is present regardless.) Modified code is attached (note that the "run simulation" menu item will cause a crash.), it is a quick hack job but I'm not seeing an obvious cause for the diff.

This is the main frame GUI


This is the separate plot generated in a new frame.





---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWidgets headers)
#ifndef WX_PRECOMP
        #include "wx/wx.h"
        #include "wx/log.h"

        #include "wx/app.h"
        #include "wx/frame.h"

        #include "wx/scrolwin.h"
        #include "wx/menu.h"
        #include "wx/textctrl.h"
        #include "wx/textdlg.h"  
#endif

#if wxUSE_UIACTIONSIMULATOR
#include "wx/uiaction.h"
#endif

#include "wx/wx.h"
#include "wx/app.h"
#include "wx/frame.h"

#include "wx/scrolwin.h"
#include "wx/menu.h"
#include "wx/textctrl.h"
#include "wx/textdlg.h"
#include "wx/intl.h"
#include "wx/file.h"
#include "wx/log.h"
#include "wx/cmdline.h"
#include "wx/calctrl.h"
#include "wx/splitter.h"
#include "wx/dcmirror.h"

// ----------------------------------------------------------------------------
// resources
// ----------------------------------------------------------------------------

// the application icon (under Windows it is in resources and even
// though we could still include the XPM here it would be unused)
#ifndef wxHAS_IMAGES_IN_RESOURCES
#include "../sample.xpm"
#endif


//*****
// Cut from wxPLplotDemo
//*****

#include "wxPLplotwindow.h"
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <math.h>
#include <complex>
#include <cmath>

using namespace std;

#define MAX( a, b )    ( ( a ) < ( b ) ? ( b ) : ( a ) )
#define MIN( a, b )    ( ( a ) < ( b ) ? ( a ) : ( b ) )
//*****

// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------

// IDs for the controls and the menu commands
enum
{
        // menu items
        RunSimulation = 1,
        SimulateText
};

// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------

//*****
//  Cut from wxPLplotDemo
//*****
template< class WXWINDOW >
void Plot(wxPLplotwindow<WXWINDOW> *plotwindow);

class wxPlFrame : public wxPLplotwindow<wxFrame>       //<wxFrame>
{
public:
        wxPlFrame(const wxString &title);
private:
        virtual void OnLocate(const PLGraphicsIn &graphicsIn);
        void OnIdle(wxIdleEvent &event);
        virtual void plot();
        bool m_plotted;
};

wxPlFrame::wxPlFrame(const wxString &title)
{
        Create(NULL, wxID_ANY, title);
                                                                   //give our 
frame a nice icon
        Connect(wxEVT_IDLE, wxIdleEventHandler(wxPlFrame::OnIdle));
        m_plotted = false;
}

void wxPlFrame::OnIdle(wxIdleEvent &event)
{
        //We do our plotting in here, but only the first time it is called
        //This allows us to keep checking if the window is ready and only
        //plot if it is.
        if (!m_plotted && IsReady())
        {
                m_plotted = true;
                plot();
        }
}

void wxPlFrame::plot()
{
        if (!IsReady())
        {
                wxMessageBox(wxT("Somehow we attempted to plot before the 
wxPLplotwindow was ready. The plot will not be drawn."));
                return;
        }
        wxPLplotstream* pls = GetStream();
        PLPLOT_wxLogDebug("wxPlDemoFrame::plot()");
        assert(pls);

        const size_t np = 500;
        PLFLT        x[np], y[np];
        PLFLT        xmin, xmax;
        PLFLT        ymin = 1e30, ymax = 1e-30;

        xmin = 0.0;
        xmax = 100.0;
        for (size_t i = 0; i < np; i++)
        {
                x[i] = (xmax - xmin) * i / np + xmin;
                y[i] = 1.0;
                y[i] = sin(x[i]) * sin(x[i] / 13.0);
                ymin = -1.05;
                ymax = -ymin;
        }

        pls->scolbg(255, 255, 255);
        pls->scol0(1, 0, 0, 0);
        pls->scol0(2, 0, 130, 130);

        pls->adv(0);
        pls->col0(1);
        pls->env(xmin, xmax, ymin, ymax, 0, 0);
        pls->lab("x", "y", "sin(x) * sin(x/13)");

        pls->col0(2);
        pls->width(2);
        pls->line(np, x, y);

        RenewPlot();
}

void wxPlFrame::OnLocate(const PLGraphicsIn &graphicsIn)
{
        if (graphicsIn.button == 0)
                return;         //Do nothing for motion, only respond to clicks

        wxString message;

        if ((graphicsIn.state & PL_MASK_SHIFT) != 0)
                message << "Shift-";
        if ((graphicsIn.state & PL_MASK_CAPS) != 0)
                message << "Caps Lock-";
        if ((graphicsIn.state & PL_MASK_CONTROL) != 0)
                message << "Ctrl-";
        if ((graphicsIn.state & PL_MASK_ALT) != 0)
                message << "Alt-";
        if ((graphicsIn.state & PL_MASK_NUM) != 0)
                message << "Num Lock-";
        if ((graphicsIn.state & PL_MASK_ALTGR) != 0)
                message << "Alt Gr-";
        if ((graphicsIn.state & PL_MASK_WIN) != 0)
                message << "Win-";
        if ((graphicsIn.state & PL_MASK_SCROLL) != 0)
                message << "Scroll Lock-";

        if (graphicsIn.button == 1)
                message << "Left click.\n";
        else if (graphicsIn.button == 2)
                message << "Middle click.\n";
        else if (graphicsIn.button == 3)
                message << "Right click.\n";
        message << "Pixels: x = " << graphicsIn.pX << " y = " << graphicsIn.pY 
<< ".\n";
        if (graphicsIn.subwindow >= 0)
        {
                message << "World: x = " << graphicsIn.wX << " y = " << 
graphicsIn.wY << ".\n";
                message << "Window = " << graphicsIn.subwindow << ".\n";
        }
        else
        {
                message << "Point is not in a Window.\n";
        }
        wxMessageBox(message, "Mouse capture demo");
}
//*****

class wxPlPanel : public wxPLplotwindow<wxPanel>       //<wxFrame>
{
public:
        wxPlPanel(wxWindow &parentP, const wxString &title);
private:
        virtual void OnLocate(const PLGraphicsIn &graphicsIn);
        void OnIdle(wxIdleEvent &event);
        virtual void plot();
        bool m_plotted;
};

wxPlPanel::wxPlPanel(wxWindow &parentP, const wxString &title)
{
        Create(&parentP, wxID_ANY);    // , title);
        //give our frame a nice icon
        Connect(wxEVT_IDLE, wxIdleEventHandler(wxPlPanel::OnIdle));
        m_plotted = false;
}

void wxPlPanel::OnIdle(wxIdleEvent &event)
{
        //We do our plotting in here, but only the first time it is called
        //This allows us to keep checking if the window is ready and only
        //plot if it is.
        if (!m_plotted && IsReady())
        {
                m_plotted = true;
                plot();
        }
}

void wxPlPanel::plot()
{
        if (!IsReady())
        {
                wxMessageBox(wxT("Somehow we attempted to plot before the 
wxPLplotwindow was ready. The plot will not be drawn."));
                return;
        }
        wxPLplotstream* pls = GetStream();
        PLPLOT_wxLogDebug("wxPlDemoFrame::plot()");
        assert(pls);

        const size_t np = 500;
        PLFLT        x[np], y[np];
        PLFLT        xmin, xmax;
        PLFLT        ymin = 1e30, ymax = 1e-30;

        xmin = 0.0;
        xmax = 100.0;
        for (size_t i = 0; i < np; i++)
        {
                x[i] = (xmax - xmin) * i / np + xmin;
                y[i] = 1.0;
                y[i] = sin(x[i]) * sin(x[i] / 13.0);
                ymin = -1.05;
                ymax = -ymin;
        }

        pls->scolbg(255, 255, 255);
        pls->scol0(1, 0, 0, 0);
        pls->scol0(2, 0, 130, 130);

        pls->adv(0);
        pls->col0(1);
        pls->env(xmin, xmax, ymin, ymax, 0, 0);
        pls->lab("x", "y", "sin(x) * sin(x/13)");

        pls->col0(2);
        pls->width(2);
        pls->line(np, x, y);

        RenewPlot();
}

void wxPlPanel::OnLocate(const PLGraphicsIn &graphicsIn)
{
        if (graphicsIn.button == 0)
                return;         //Do nothing for motion, only respond to clicks

        wxString message;

        if ((graphicsIn.state & PL_MASK_SHIFT) != 0)
                message << "Shift-";
        if ((graphicsIn.state & PL_MASK_CAPS) != 0)
                message << "Caps Lock-";
        if ((graphicsIn.state & PL_MASK_CONTROL) != 0)
                message << "Ctrl-";
        if ((graphicsIn.state & PL_MASK_ALT) != 0)
                message << "Alt-";
        if ((graphicsIn.state & PL_MASK_NUM) != 0)
                message << "Num Lock-";
        if ((graphicsIn.state & PL_MASK_ALTGR) != 0)
                message << "Alt Gr-";
        if ((graphicsIn.state & PL_MASK_WIN) != 0)
                message << "Win-";
        if ((graphicsIn.state & PL_MASK_SCROLL) != 0)
                message << "Scroll Lock-";

        if (graphicsIn.button == 1)
                message << "Left click.\n";
        else if (graphicsIn.button == 2)
                message << "Middle click.\n";
        else if (graphicsIn.button == 3)
                message << "Right click.\n";
        message << "Pixels: x = " << graphicsIn.pX << " y = " << graphicsIn.pY 
<< ".\n";
        if (graphicsIn.subwindow >= 0)
        {
                message << "World: x = " << graphicsIn.wX << " y = " << 
graphicsIn.wY << ".\n";
                message << "Window = " << graphicsIn.subwindow << ".\n";
        }
        else
        {
                message << "Point is not in a Window.\n";
        }
        wxMessageBox(message, "Mouse capture demo");
}
//*****


// Define a new application type, each program should derive a class from wxApp
class MyApp : public wxApp
{
public:
        MyApp() { }
        virtual bool OnInit() wxOVERRIDE;

        wxDECLARE_NO_COPY_CLASS(MyApp);
};

#if wxUSE_UIACTIONSIMULATOR

// Define a new frame type: this is going to be our main frame
class MyFrame : public wxFrame
{
public:
        MyFrame();

        void OnButtonPressed(wxCommandEvent& event);
        void OnRunSimulation(wxCommandEvent& event);
        void OnSimulateText(wxCommandEvent& event);
        void OnExit(wxCommandEvent& WXUNUSED(event)) { Close(); }

private:
        wxButton* m_button;
        wxTextCtrl* m_text;

        //  New code from GUI to test plotting realestate.
        //  May need to declare one of these a wxPLplotwindow<>
        wxPLplotwindow<wxPanel> *m_right;
        wxTextCtrl *m_left;

        wxSplitterWindow* m_splitter;
        wxWindow *m_replacewindow;

        wxDECLARE_EVENT_TABLE();
        wxDECLARE_NO_COPY_CLASS(MyFrame);
};

class windowDefine : public wxSplitterWindow
{
public:
        windowDefine(wxFrame *parent);

private:
        wxFrame *m_frame;
        wxDECLARE_NO_COPY_CLASS(windowDefine);
};


wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_BUTTON(wxID_ANY, MyFrame::OnButtonPressed)
EVT_MENU(RunSimulation, MyFrame::OnRunSimulation)
EVT_MENU(SimulateText, MyFrame::OnSimulateText)
EVT_MENU(wxID_EXIT, MyFrame::OnExit)
wxEND_EVENT_TABLE()

#endif // wxUSE_UIACTIONSIMULATOR

// ============================================================================
// implementation
// ============================================================================

// ----------------------------------------------------------------------------
// the application class
// ----------------------------------------------------------------------------

wxIMPLEMENT_APP(MyApp);

bool MyApp::OnInit()
{
        if (!wxApp::OnInit())
                return false;

#if wxUSE_UIACTIONSIMULATOR
        MyFrame *frame = new MyFrame;  //("wxUIActionSimulator sample 
application");
        frame->Show(true);

        return true;
#else // !wxUSE_UIACTIONSIMULATOR
        wxLogError("wxUSE_UIACTIONSIMULATOR must be 1 for this sample");
        return false;
#endif // wxUSE_UIACTIONSIMULATOR/!wxUSE_UIACTIONSIMULATOR
}

// ----------------------------------------------------------------------------
// main frame
// ----------------------------------------------------------------------------

#if wxUSE_UIACTIONSIMULATOR

// frame constructor
MyFrame::MyFrame()
        : wxFrame(NULL, wxID_ANY, wxT("Test!"),
                wxDefaultPosition, wxSize(1020, 600),
                wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE)
{
        SetIcon(wxICON(sample));

#if wxUSE_MENUS
        // create a menu bar
        wxMenu *fileMenu = new wxMenu;

        fileMenu->Append(wxID_NEW, "&New File...", "Open a new file");
        fileMenu->Append(RunSimulation, "&Run Simulation",
                "Run predefined UI action simulation");
        fileMenu->Append(SimulateText, "Simulate &text input...",
                "Enter text to simulate");
        fileMenu->AppendSeparator();

        fileMenu->Append(wxID_EXIT, "E&xit\tAlt-X", "Quit this program");

        wxMenuBar *menuBar = new wxMenuBar();
        menuBar->Append(fileMenu, "&File");

        SetMenuBar(menuBar);
#endif // wxUSE_MENUS

        //  Here the panel is created and "attached" to the main frame.
        //  Try initializing the plplot graph inside here.  
        //  Also try making it a pannel and inheriting this frame, or pannel.


        //  Right here we create a new panel with "this" pointer, which 
"attaches" it to the main frame.
        //  Then we make it a vertical split and size it.
        //  Can we do this with a plplot object?
        //  It would appear that the wxplplotwindow inherits the attributes and 
functions on the wxType used to 
        //  define it.  

        
        //wxPanel *panel = new wxPanel(this);


        //wxPlPanel *inheritedFrame = new wxPlPanel(panel, wxT("wxPLplotDemo - 
Interactive Frame With Inheritance"));
        //inheritedFrame->Show();

        //*******The second method using no inheritance*******
        //Use two stage window creation to first construct the frame using the 
wxPLplotwindow
        //constructor, then pass in the appropriate wxFrame parameters
        
        wxPLplotwindow<wxFrame> *inheritedFrame = new wxPLplotwindow<wxFrame>();
        inheritedFrame->Create(this, wxID_ANY, wxT("wxPLplotDemo - Where am 
I!"));
        PLPLOT_wxLogDebug("frame->Create");

        inheritedFrame->Show();

        //We must wait for the wxEVT_CREATE event to be processed and the
        //wxPLplotstream to be prepared.
        while (!inheritedFrame->IsReady())
        {
                PLPLOT_wxLogDebug("Plot() Yielding");
                wxGetApp().Yield();
        }

        //Now we can set up our frame and do the plotting
        Plot(inheritedFrame);

        
        //  Here is a new attempt which uses the splitter window and tries to 
get a plot in one of the windows.
        m_splitter = new windowDefine(this);
        m_splitter->SetSize(GetClientSize());
        m_splitter->SetSashGravity(1.0);

        m_left = new wxTextCtrl(m_splitter, wxID_ANY, wxEmptyString,
                wxDefaultPosition, wxDefaultSize,
                wxTE_MULTILINE | wxTE_READONLY);

        m_left->SetFocus();
        m_left->ShowNativeCaret(false);

        m_left->SetMaxLength(10000);

        m_right = new wxPLplotwindow<wxPanel>();
        m_right->Create(m_splitter, wxID_ANY);   //wxT("wxPLplotDemo - 
Non-interactive Directly Created Frame"));
        
        //m_right->SetBackgroundColour(*wxWHITE);
        m_splitter->SplitVertically(m_left, m_right, 200);

        Plot(m_right);
        
        //wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
        //panel->SetSizer(sizer);
        //inheritedFrame->SetSizer(sizer);

        //m_button = new wxButton(inheritedFrame, wxID_ANY, "&Button");  
//panel, wxID_ANY, "&Button");
        //sizer->Add(m_button, wxSizerFlags().Centre().Border());

        //m_text = new wxTextCtrl(inheritedFrame, wxID_ANY, "",     //panel, 
wxID_ANY, "",
        //      wxDefaultPosition, wxDefaultSize,
        //      wxTE_MULTILINE);
        //sizer->Add(m_text, wxSizerFlags(1).Expand().Border());
        m_replacewindow = NULL;
}

//  New plotting function for second method
template< class WXWINDOW >
void Plot(wxPLplotwindow<WXWINDOW> *plotwindow)
{
        if (!plotwindow->IsReady())
        {
                wxMessageBox(wxT("Somehow we attempted to plot before the 
wxPLplotwindow was ready. The plot will not be drawn."));
                return;
        }
        wxPLplotstream* pls = plotwindow->GetStream();
        PLPLOT_wxLogDebug("Plot()");
        assert(pls);

        const size_t np = 500;
        PLFLT        x[np], y[np];
        PLFLT        xmin, xmax;
        PLFLT        ymin = 1e30, ymax = 1e-30;

        xmin = -2.0;
        xmax = 10.0;
        for (size_t i = 0; i < np; i++)
        {
                x[i] = (xmax - xmin) * i / np + xmin;
                y[i] = 1.0;
                if (x[i] != 0.0)
                        y[i] = sin(x[i]) / x[i];
                ymin = MIN(ymin, y[i]);
                ymax = MAX(ymax, y[i]);
        }


        pls->scolbg(255, 255, 255);
        pls->scol0(1, 0, 0, 0);
        pls->scol0(2, 0, 130, 130);




        pls->adv(0);

        pls->ssub(1, 2);

        pls->col0(15);
        pls->env(xmin, xmax, ymin, ymax, 0, 0);
        pls->col0(2);
        pls->lab("x", "y", "sin(x)/x");

        pls->col0(3);
        pls->width(2);
        pls->line(np, x, y);

        pls->adv(1);
        pls->col0(15);
        pls->env(xmin, xmax, ymin, ymax, 0, 0);
        pls->col0(2);
        pls->lab("x", "y", "sin(x)/x");

        pls->col0(3);
        pls->width(2);
        pls->line(np, x, y);


        plotwindow->RenewPlot();
}



// event handlers

void MyFrame::OnRunSimulation(wxCommandEvent& WXUNUSED(event))
{
        wxUIActionSimulator sim;

        // Add some extra distance to take account of window decorations
        sim.MouseMove(m_button->GetScreenPosition() + wxPoint(10, 10));
        sim.MouseClick(wxMOUSE_BTN_LEFT);

        // Process the resulting button event
        wxYield();

        m_text->SetFocus();
        sim.Char('A');
        sim.Char('A', wxMOD_SHIFT);
        sim.Char(WXK_RETURN);
        sim.Char('Z');
        sim.Char('Z', wxMOD_SHIFT);
        sim.Char(WXK_RETURN);
        sim.Text("aAbBcC");
        sim.Char(WXK_RETURN);
        sim.Text("1 234.57e-8");
        sim.Char(WXK_RETURN);

}

void MyFrame::OnSimulateText(wxCommandEvent& WXUNUSED(event))
{
/*      
        static wxString s_text;
        const wxString text = wxGetTextFromUser
        (
                "Enter text to simulate: ",
                "wxUIActionSimulator wxWidgets Sample",
                s_text,
                this
        );
        if (text.empty())
                return;

        s_text = text;

        wxUIActionSimulator sim;
        m_text->SetFocus();
        sim.Text(s_text.c_str());
        
*/

        wxPlFrame *inheritedFrame = new wxPlFrame(wxT("wxPLplotDemo - 
Interactive Frame With Inheritance"));
        inheritedFrame->Show();
}

void MyFrame::OnButtonPressed(wxCommandEvent& WXUNUSED(event))
{
        m_text->AppendText("Button pressed.\n");
        
        //*******The first method using the child class defined above******
        //wxPlPanel *inheritedFrame = new wxPlPanel(wxT("wxPLplotDemo - 
Interactive Frame With Inheritance"));
        //inheritedFrame->Show();


        //delete x;
}

#endif // wxUSE_UIACTIONSIMULATOR

windowDefine::windowDefine(wxFrame *parent)
        : wxSplitterWindow(parent, wxID_ANY,
                wxDefaultPosition, wxDefaultSize,
                wxSP_3D | wxSP_LIVE_UPDATE |
                wxCLIP_CHILDREN /* | wxSP_NO_XP_THEME */)
{
        m_frame = parent;
}
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Plplot-general mailing list
Plplot-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-general

Reply via email to