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