main.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. #include <iostream>
  2. #include <utility>
  3. #include <memory>
  4. #include <vector>
  5. // For compilers that support precompilation, includes "wx/wx.h".
  6. #include <wx/wxprec.h>
  7. #ifndef WX_PRECOMP
  8. #include <wx/wx.h>
  9. #endif
  10. #include <wx/tglbtn.h>
  11. #include <wx/combobox.h>
  12. #include <wx/msgdlg.h>
  13. #include <wx/glcanvas.h>
  14. #include <wx/notebook.h>
  15. class Renderer {
  16. protected:
  17. wxGLCanvas *m_canvas;
  18. std::unique_ptr<wxGLContext> m_context;
  19. public:
  20. Renderer(wxGLCanvas *c): m_canvas{c} {
  21. m_context = std::make_unique<wxGLContext>(m_canvas);
  22. }
  23. wxGLContext * context() { return m_context.get(); }
  24. const wxGLContext * context() const { return m_context.get(); }
  25. void set_active()
  26. {
  27. m_canvas->SetCurrent(*m_context);
  28. // Set the current clear color to sky blue and the current drawing color to
  29. // white.
  30. glClearColor(0.1, 0.39, 0.88, 1.0);
  31. glColor3f(1.0, 1.0, 1.0);
  32. // Tell the rendering engine not to draw backfaces. Without this code,
  33. // all four faces of the tetrahedron would be drawn and it is possible
  34. // that faces farther away could be drawn after nearer to the viewer.
  35. // Since there is only one closed polyhedron in the whole scene,
  36. // eliminating the drawing of backfaces gives us the realism we need.
  37. // THIS DOES NOT WORK IN GENERAL.
  38. glEnable(GL_CULL_FACE);
  39. glCullFace(GL_BACK);
  40. // Set the camera lens so that we have a perspective viewing volume whose
  41. // horizontal bounds at the near clipping plane are -2..2 and vertical
  42. // bounds are -1.5..1.5. The near clipping plane is 1 unit from the camera
  43. // and the far clipping plane is 40 units away.
  44. glMatrixMode(GL_PROJECTION);
  45. glLoadIdentity();
  46. glFrustum(-2, 2, -1.5, 1.5, 1, 40);
  47. // Set up transforms so that the tetrahedron which is defined right at
  48. // the origin will be rotated and moved into the view volume. First we
  49. // rotate 70 degrees around y so we can see a lot of the left side.
  50. // Then we rotate 50 degrees around x to "drop" the top of the pyramid
  51. // down a bit. Then we move the object back 3 units "into the screen".
  52. glMatrixMode(GL_MODELVIEW);
  53. glLoadIdentity();
  54. glTranslatef(0, 0, -3);
  55. glRotatef(50, 1, 0, 0);
  56. glRotatef(70, 0, 1, 0);
  57. }
  58. void draw_scene(long w, long h)
  59. {
  60. glViewport(0, 0, GLsizei(w), GLsizei(h));
  61. glClear(GL_COLOR_BUFFER_BIT);
  62. // Draw a white grid "floor" for the tetrahedron to sit on.
  63. glColor3f(1.0, 1.0, 1.0);
  64. glBegin(GL_LINES);
  65. for (GLfloat i = -2.5; i <= 2.5; i += 0.25) {
  66. glVertex3f(i, 0, 2.5); glVertex3f(i, 0, -2.5);
  67. glVertex3f(2.5, 0, i); glVertex3f(-2.5, 0, i);
  68. }
  69. glEnd();
  70. // Draw the tetrahedron. It is a four sided figure, so when defining it
  71. // with a triangle strip we have to repeat the last two vertices.
  72. glBegin(GL_TRIANGLE_STRIP);
  73. glColor3f(1, 1, 1); glVertex3f(0, 2, 0);
  74. glColor3f(1, 0, 0); glVertex3f(-1, 0, 1);
  75. glColor3f(0, 1, 0); glVertex3f(1, 0, 1);
  76. glColor3f(0, 0, 1); glVertex3f(0, 0, -1.4);
  77. glColor3f(1, 1, 1); glVertex3f(0, 2, 0);
  78. glColor3f(1, 0, 0); glVertex3f(-1, 0, 1);
  79. glEnd();
  80. glFlush();
  81. }
  82. void swap_buffers() { m_canvas->SwapBuffers(); }
  83. };
  84. // The top level frame of the application.
  85. class MyFrame: public wxFrame
  86. {
  87. wxGLCanvas *m_canvas;
  88. std::unique_ptr<Renderer> m_renderer;
  89. public:
  90. MyFrame(const wxString & title,
  91. const wxPoint & pos,
  92. const wxSize & size);
  93. wxGLCanvas * canvas() { return m_canvas; }
  94. const wxGLCanvas * canvas() const { return m_canvas; }
  95. };
  96. class App : public wxApp {
  97. MyFrame *m_frame = nullptr;
  98. wxString m_fname;
  99. public:
  100. bool OnInit() override {
  101. m_frame = new MyFrame("Wayland wxNotebook issue", wxDefaultPosition, wxSize(1024, 768));
  102. m_frame->Show( true );
  103. return true;
  104. }
  105. };
  106. wxIMPLEMENT_APP(App);
  107. MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size):
  108. wxFrame(nullptr, wxID_ANY, title, pos, size)
  109. {
  110. wxMenu *menuFile = new wxMenu;
  111. menuFile->Append(wxID_OPEN);
  112. menuFile->Append(wxID_EXIT);
  113. wxMenuBar *menuBar = new wxMenuBar;
  114. menuBar->Append( menuFile, "&File" );
  115. SetMenuBar( menuBar );
  116. auto notebookpanel = new wxPanel(this);
  117. auto notebook = new wxNotebook(notebookpanel, wxID_ANY);
  118. auto maintab = new wxPanel(notebook);
  119. m_canvas = new wxGLCanvas(maintab,
  120. wxID_ANY,
  121. nullptr,
  122. wxDefaultPosition,
  123. wxDefaultSize,
  124. wxWANTS_CHARS | wxFULL_REPAINT_ON_RESIZE);
  125. m_renderer = std::make_unique<Renderer>(m_canvas);
  126. wxPanel *control_panel = new wxPanel(maintab);
  127. auto controlsizer = new wxBoxSizer(wxHORIZONTAL);
  128. auto console_sizer = new wxBoxSizer(wxVERTICAL);
  129. std::vector<wxString> combolist = {"One", "Two", "Three"};
  130. auto combobox = new wxComboBox(control_panel, wxID_ANY, combolist[0],
  131. wxDefaultPosition, wxDefaultSize,
  132. int(combolist.size()), combolist.data());
  133. auto sz = new wxBoxSizer(wxHORIZONTAL);
  134. sz->Add(new wxStaticText(control_panel, wxID_ANY, "Choose number"), 0,
  135. wxALL | wxALIGN_CENTER, 5);
  136. sz->Add(combobox, 1, wxALL | wxEXPAND, 5);
  137. console_sizer->Add(sz, 0, wxEXPAND);
  138. auto btn1 = new wxToggleButton(control_panel, wxID_ANY, "Button1");
  139. console_sizer->Add(btn1, 0, wxALL | wxEXPAND, 5);
  140. auto btn2 = new wxToggleButton(control_panel, wxID_ANY, "Button2");
  141. btn2->SetValue(true);
  142. console_sizer->Add(btn2, 0, wxALL | wxEXPAND, 5);
  143. controlsizer->Add(console_sizer, 1, wxEXPAND);
  144. control_panel->SetSizer(controlsizer);
  145. auto maintab_sizer = new wxBoxSizer(wxHORIZONTAL);
  146. maintab_sizer->Add(m_canvas, 1, wxEXPAND);
  147. maintab_sizer->Add(control_panel, 0);
  148. maintab->SetSizer(maintab_sizer);
  149. notebook->AddPage(maintab, "Main");
  150. wxTextCtrl* textCtrl1 = new wxTextCtrl(notebook, wxID_ANY, L"Tab 2 Contents");
  151. notebook->AddPage(textCtrl1, "Dummy");
  152. auto notebooksizer = new wxBoxSizer(wxHORIZONTAL);
  153. notebooksizer->Add(notebook, 1, wxEXPAND);
  154. notebookpanel->SetSizer(notebooksizer);
  155. auto topsizer = new wxBoxSizer(wxHORIZONTAL);
  156. topsizer->Add(notebookpanel, 1, wxEXPAND);
  157. SetSizer(topsizer);
  158. SetMinSize(size);
  159. Bind(wxEVT_MENU, [this](wxCommandEvent &) {
  160. wxFileDialog dlg(this, "Select file", wxEmptyString,
  161. wxEmptyString, "*.*", wxFD_OPEN|wxFD_FILE_MUST_EXIST);
  162. dlg.ShowModal();
  163. }, wxID_OPEN);
  164. Bind(wxEVT_MENU, [this](wxCommandEvent &) {
  165. Close();
  166. }, wxID_EXIT);
  167. Bind(wxEVT_SHOW, [this](wxShowEvent &) {
  168. m_renderer->set_active();
  169. m_canvas->Bind(wxEVT_PAINT, [this](wxPaintEvent &){
  170. wxPaintDC dc(m_canvas);
  171. const wxSize sz = m_canvas->GetClientSize();
  172. m_renderer->draw_scene(sz.x, sz.y);
  173. m_renderer->swap_buffers();
  174. });
  175. });
  176. }