[wxWidgets] wxGLCanvas i wxTextCtrl

0

Nagłówek:

# pragma once
# include "wx/glcanvas.h"

enum
{ BASIC_EXIT    =   1,
  BASIC_OPEN    = 100,
  BASIC_ABOUT   = 200
};

class BasicApplication : public wxApp
{
  public:
        virtual bool OnInit();
};


class TestGLCanvas: public wxGLCanvas
{
	bool   m_init;

	protected:
		DECLARE_EVENT_TABLE()

	public:
		TestGLCanvas( wxWindow *parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = _T("TestGLCanvas") );

	~TestGLCanvas();

	void OnPaint(wxPaintEvent& event);
	void OnSize(wxSizeEvent& event);
	void OnEraseBackground(wxEraseEvent& event);
	void OnEnterWindow(wxMouseEvent& event);

	void Render();
	void InitGL();

};

class BasicFrame : public wxFrame
{
 
  public:
        BasicFrame( const wxChar *title, int xpos, int ypos, int width, int height);
        ~BasicFrame();
        wxBoxSizer *sizer;
		wxTextCtrl *theText;
        wxMenuBar  *menuBar;
        wxMenu     *fileMenu;
};

 
#include <wx/wx.h>
#include "basic.h"
 
/*----------------------------------------------------------------
  Implementation of Test-GLCanvas
-----------------------------------------------------------------*/

BEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas)
    EVT_SIZE(TestGLCanvas::OnSize)
    EVT_PAINT(TestGLCanvas::OnPaint)
    EVT_ERASE_BACKGROUND(TestGLCanvas::OnEraseBackground)
    EVT_ENTER_WINDOW( TestGLCanvas::OnEnterWindow )
END_EVENT_TABLE()



TestGLCanvas::TestGLCanvas(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name)
    : wxGLCanvas(parent, (wxGLCanvas*) NULL, id, pos, size, style|wxFULL_REPAINT_ON_RESIZE , name )
{

}



TestGLCanvas::~TestGLCanvas()
{
}

void TestGLCanvas::Render()
{
    wxPaintDC dc(this);

#ifndef __WXMOTIF__
    if (!GetContext()) return;
#endif

    SetCurrent();
    // Init OpenGL once, but after SetCurrent
    if (!m_init)
    {
        InitGL();
        m_init = true;
    }

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glMatrixMode(GL_MODELVIEW);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glLoadIdentity();													
	glBegin(GL_TRIANGLES);
		glColor3f(1.0f,0.0f,0.0f);
		glVertex3f( 0.0f, 1.0f, 0.0f);
		glColor3f(0.0f,1.0f,0.0f);
		glVertex3f(-1.0f,-1.0f, 0.0f);
		glColor3f(0.0f,0.0f,1.0f);
		glVertex3f( 1.0f,-1.0f, 0.0f);
	glEnd();
	glTranslatef(3.0f,0.0f,0.0f);
	glColor3f(0.5f,0.5f,1.0f);
	glBegin(GL_QUADS);
		glVertex3f(-1.0f, 1.0f, 0.0f);
		glVertex3f( 1.0f, 1.0f, 0.0f);
		glVertex3f( 1.0f,-1.0f, 0.0f);	
		glVertex3f(-1.0f,-1.0f, 0.0f);
	glEnd();

    glFlush();
    SwapBuffers();
}

void TestGLCanvas::OnEnterWindow( wxMouseEvent& WXUNUSED(event) )
{
    SetFocus();
}

void TestGLCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) )
{
    Render();
}

void TestGLCanvas::OnSize(wxSizeEvent& event)
{

    wxGLCanvas::OnSize(event);

    int w, h;
    GetClientSize(&w, &h);
#ifndef __WXMOTIF__
    if (GetContext())
#endif
    {
        SetCurrent();
        glViewport(0, 0, (GLint) w, (GLint) h);
    }
}

void TestGLCanvas::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
{

}

void TestGLCanvas::InitGL()
{
    SetCurrent();
    glMatrixMode(GL_PROJECTION);
}



BasicFrame::BasicFrame(const wxChar *title, int xpos, int ypos, int width, int height)
             : wxFrame( (wxFrame *) NULL, -1, title, wxPoint(xpos, ypos), wxSize(width, height))
{
  theText = (wxTextCtrl *) NULL;
    int w, h;
    GetClientSize(&w, &h);   

sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add( new TestGLCanvas(this, wxID_ANY, wxDefaultPosition, wxSize(w,h-20) ));
sizer->Add(new wxTextCtrl(this, wxID_ANY, wxT("Type a command."), wxPoint(0, 510), wxSize(400, 20), wxTE_PROCESS_ENTER)); 
 
SetSizer(sizer);

}


BasicFrame::~BasicFrame()
{
}

// ---------------------------------------

IMPLEMENT_APP(BasicApplication)

bool BasicApplication::OnInit()
{
  BasicFrame *frame = new BasicFrame("Turtle", 200, 200, 800, 600);
  frame->Show(TRUE);
  SetTopWindow(frame);
  return TRUE; 
}
 

Pytanie: jak w wxGLCanvas obsłużyć event naciśnięcia Enter w kontrolce wxTextCtrl.
Wiem, że trzeba skorzystać z wxEVENT_TYPE_TEXT_ENTER_COMMAND, ale nie mam pojęcia jak. Chodzi mi o to, żeby po wpisaniu czegoś w wxTextCtrl np. poruszyć tym, co jest wyświetlane w wxGLCanvas

0

Normalnie dodaj handler do event table, tylko musisz określić ID edita (nie może być wxID_ANY), lub łącz dynamicznie metodą wxTextCtrl::Connect jeżeli chcesz mieć dynamicznie przydzielany ID.

0

W klasie BasicFrame zadeklaruj pole TestGLCanvas*tlgc;
W konstruktorze przypisz do niego twój obiekt canvas a dopiero potem dodaj do sizera. Dalej w klase BasicFrame zrób obsługę zdarzenia wxEVT_COMMAND_TEXT_ENTER makrem EVT_TEXT_ENTER(id, func) albo inaczej. I teraz w funkcji obsugi masz dostep do obu kontrolek, czyli z gorki.

0
BEGIN_EVENT_TABLE(BasicFrame, wxFrame)
	EVT_TEXT_ENTER(ID_TEXT_ENTERED, TestGLCanvas::OnWxTextCtrl) 
END_EVENT_TABLE()

Zrobiłem coś takiego. ID się zgadza z wxTextCtrl. Ale dalej nic...

0

A co tam robi TestGLCanvas???

0

To jak mam wywołać odpowiednią funkcję?

0

Robisz tak:

BEGIN_EVENT_TABLE(BasicFrame, wxFrame)
        EVT_TEXT_ENTER(ID_TEXT_ENTERED, BasicFrame::OnWxTextCtrl)
END_EVENT_TABLE()

Robisz metodę BasicFrame::OnWxTextCtrl i tam dajesz obsługę/interakcję z TestGLCanvas. Ewentualnie możesz użyć łączenia dynamicznego:

TestGLCanvas*   m_test_gl_canvas;
wxTextCtrl*        m_text_ctrl;
...
m_text_ctrl->Connect(m_text_ctrl->GetId(),wxEVT_COMMAND_TEXT_ENTER,wxCommandEventHandler(TestGLCanvas::OnWxTextCtrl),NULL,m_test_gl_canvas);

wtedy obsługę będziesz miał w klasie TestGLCanvas.

PS. mogłem się gdzieś pomylić.

0

Do TestGLCanvas::OnWxTextCtrl dodałem jeszcze funkcję Refresh() i działa. Chyba właśnie tego Refresh brakowało we wszystkich moich próbach obsłużenia tego event.

Dzięki za pomoc.

0

No niekoniecznie bo coś takiego:

BEGIN_EVENT_TABLE(BasicFrame, wxFrame)
        EVT_TEXT_ENTER(ID_TEXT_ENTERED, TestGLCanvas::OnWxTextCtrl)
END_EVENT_TABLE()

wywoła wprawdzie metodę OnWxTextCtrl klasy TestGLCanvas, ale this wewnątrz tej metody będzie wskazywał na BasicFrame - błąd, który wyjdzie gdy zaczniesz odwoływać się do specyficznych danych/metod klasy TestGLCanvas.

1 użytkowników online, w tym zalogowanych: 0, gości: 1