nux-1.16.0
|
00001 /* 00002 * Copyright 2010 Inalogic Inc. 00003 * 00004 * This program is free software: you can redistribute it and/or modify it 00005 * under the terms of the GNU General Public License version 3, as published 00006 * by the Free Software Foundation. 00007 * 00008 * This program is distributed in the hope that it will be useful, but 00009 * WITHOUT ANY WARRANTY; without even the implied warranties of 00010 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 00011 * PURPOSE. See the GNU General Public License for more details. 00012 * 00013 * You should have received a copy of the GNU General Public License 00014 * version 3 along with this program. If not, see 00015 * <http://www.gnu.org/licenses/> 00016 * 00017 * Authored by: Jay Taoko <jaytaoko@inalogic.com> 00018 * 00019 */ 00020 00021 #include "Nux/Nux.h" 00022 #include "Nux/VLayout.h" 00023 #include "Nux/HLayout.h" 00024 #include "Nux/WindowThread.h" 00025 #include "Nux/TextEntry.h" 00026 #include "Nux/ScrollView.h" 00027 #include "Nux/GridHLayout.h" 00028 #include "Nux/GridVLayout.h" 00029 #include "Nux/TextureArea.h" 00030 #include "Nux/Panel.h" 00031 #include "Nux/MenuPage.h" 00032 #include "NuxCore/Logger.h" 00033 00034 #include "NuxGraphics/IOpenGLFrameBufferObject.h" 00035 #include "NuxGraphics/IOpenGLBaseTexture.h" 00036 00037 nux::NString tile_vertex_shader = TEXT (" \n\ 00038 #version 110 \n\ 00039 attribute vec4 position; \n\ 00040 attribute vec4 texcoord; \n\ 00041 attribute vec4 color; \n\ 00042 uniform mat4 mvp_matrix; \n\ 00043 varying vec4 texcoord0; \n\ 00044 varying vec4 color0; \n\ 00045 void main() \n\ 00046 { \n\ 00047 texcoord0 = texcoord; \n\ 00048 color0 = color; \n\ 00049 gl_Position = mvp_matrix * position; \n\ 00050 }"); 00051 00052 nux::NString tile_fragment_shader = TEXT (" \n\ 00053 #version 110 \n\ 00054 varying vec4 texcoord0; \n\ 00055 varying vec4 color0; \n\ 00056 uniform sampler2D texture_unit0; \n\ 00057 void main() \n\ 00058 { \n\ 00059 gl_FragColor = color0; \n\ 00060 }"); 00061 00062 00063 class Tile; 00064 00065 class TilesView: public nux::View 00066 { 00067 NUX_DECLARE_OBJECT_TYPE(TilesView, View); 00068 public: 00069 TilesView(NUX_FILE_LINE_PROTO); 00070 ~TilesView(); 00071 00072 void AddTile(Tile *tile); 00073 00074 protected: 00075 nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type); 00076 void OnMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags); 00077 void ShowPopupMenu(int x, int y); 00078 00079 void Draw(nux::GraphicsEngine &graphics_engine, bool force_draw); 00080 void DrawContent(nux::GraphicsEngine &graphics_engine, bool force_draw); 00081 00082 private: 00083 Tile *focus_tile_; 00084 nux::GridHLayout *grid_layout_; 00085 nux::MenuPage *popup_menu_; 00086 nux::ColorLayer background_color_layer_; 00087 }; 00088 00089 class Tile: public nux::TextureArea 00090 { 00091 NUX_DECLARE_OBJECT_TYPE(Tile, TextureArea); 00092 public: 00093 Tile(NUX_FILE_LINE_PROTO); 00094 ~Tile(); 00095 00096 protected: 00097 void OnMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); 00098 void Draw(nux::GraphicsEngine &graphics_engine, bool force_draw); 00099 00100 private: 00101 nux::ObjectPtr<nux::IOpenGLFrameBufferObject> fbo_; 00102 nux::ObjectPtr<nux::IOpenGLBaseTexture> texture_; 00103 nux::ObjectPtr<nux::IOpenGLBaseTexture> depth_texture_; 00104 00105 nux::ObjectPtr<nux::IOpenGLPixelShader> fragment_shader_prog_; 00106 nux::ObjectPtr<nux::IOpenGLVertexShader> vertex_shader_prog_; 00107 nux::ObjectPtr<nux::IOpenGLShaderProgram> shader_prog_; 00108 }; 00109 00110 NUX_IMPLEMENT_OBJECT_TYPE(TilesView); 00111 00112 TilesView::TilesView(NUX_FILE_LINE_DECL) 00113 : View(NUX_FILE_LINE_PARAM) 00114 , background_color_layer_(nux::color::Orange, true) 00115 { 00116 popup_menu_ = new nux::MenuPage("", NUX_TRACKER_LOCATION); 00117 popup_menu_->AddAction("Position"); 00118 popup_menu_->AddAction("Remove"); 00119 popup_menu_->AddAction("Configure"); 00120 popup_menu_->SetParentObject(this); 00121 popup_menu_->SetOnClosureContinueEventCycle(true); 00122 00123 background_color_layer_.SetColor(nux::color::Orange); 00124 00125 mouse_up.connect(sigc::mem_fun(this, &TilesView::OnMouseDown)); 00126 00127 grid_layout_ = new nux::GridHLayout(NUX_TRACKER_LOCATION); 00128 grid_layout_->ForceChildrenSize(true); 00129 grid_layout_->SetChildrenSize(64, 64); 00130 grid_layout_->EnablePartialVisibility(false); 00131 00132 grid_layout_->SetVerticalExternalMargin(32); 00133 grid_layout_->SetHorizontalExternalMargin(32); 00134 grid_layout_->SetVerticalInternalMargin(32); 00135 grid_layout_->SetHorizontalInternalMargin(32); 00136 00137 grid_layout_->SetStretchFactor(1); 00138 grid_layout_->SetHeightMatchContent(false); 00139 00140 SetLayout(grid_layout_); 00141 } 00142 00143 TilesView::~TilesView() 00144 { 00145 popup_menu_->UnParentObject(); 00146 } 00147 00148 void TilesView::AddTile(Tile *tile) 00149 { 00150 if (tile == NULL) 00151 return; 00152 00153 grid_layout_->AddView(tile, 1, nux::eLeft, nux::eFull); 00154 } 00155 00156 nux::Area* TilesView::FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type) 00157 { 00158 bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type); 00159 00160 if(mouse_inside == false) 00161 return NULL; 00162 00163 if (event_type == nux::NUX_MOUSE_PRESSED) 00164 { 00165 focus_tile_ = static_cast<Tile*>(grid_layout_->FindAreaUnderMouse(mouse_position, event_type)); 00166 } 00167 else 00168 { 00169 //focus_tile_ = NULL; 00170 } 00171 00172 if((event_type == nux::NUX_MOUSE_WHEEL) && (!AcceptMouseWheelEvent())) 00173 return NULL; 00174 return this; 00175 } 00176 00177 void TilesView::OnMouseDown(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state) 00178 { 00179 if (nux::GetEventButton(mouse_button_state) == nux::NUX_MOUSE_BUTTON3) 00180 { 00181 if (focus_tile_) 00182 { 00183 ShowPopupMenu(x + 2, y + 2); 00184 } 00185 } 00186 } 00187 00188 void TilesView::ShowPopupMenu(int x, int y) 00189 { 00190 popup_menu_->StopMenu(); 00191 popup_menu_->StartMenu(x, y, 0, 0, false); 00192 } 00193 00194 void TilesView::Draw(nux::GraphicsEngine &graphics_engine, bool force_draw) 00195 { 00196 background_color_layer_.SetGeometry(GetGeometry()); 00197 background_color_layer_.Renderlayer(graphics_engine); 00198 } 00199 00200 void TilesView::DrawContent(nux::GraphicsEngine &graphics_engine, bool force_draw) 00201 { 00202 nux::GetWindowThread()->GetPainter().PushLayer(graphics_engine, GetGeometry(), &background_color_layer_); 00203 00204 if (m_CompositionLayout) 00205 m_CompositionLayout->ProcessDraw(graphics_engine, force_draw); 00206 00207 nux::GetWindowThread()->GetPainter().PopBackground(); 00208 } 00209 00210 class TileManager 00211 { 00212 public: 00213 TileManager(); 00214 ~TileManager(); 00215 00216 Tile* CreateTile(); 00217 00218 TilesView* GetTilesView(); 00219 private: 00220 TilesView* tiles_view_; 00221 nux::ObjectPtr<nux::IOpenGLFrameBufferObject> fbo_; 00222 nux::ObjectPtr<nux::IOpenGLBaseTexture> texture_; 00223 nux::ObjectPtr<nux::IOpenGLBaseTexture> depth_texture_; 00224 00225 }; 00226 00227 TileManager::TileManager() 00228 { 00229 tiles_view_ = new TilesView(NUX_TRACKER_LOCATION); 00230 } 00231 00232 TileManager::~TileManager() 00233 { 00234 00235 } 00236 00237 Tile* TileManager::CreateTile() 00238 { 00239 Tile *tile = new Tile(NUX_TRACKER_LOCATION); 00240 tiles_view_->AddTile(tile); 00241 00242 return tile; 00243 } 00244 00245 TilesView* TileManager::GetTilesView() 00246 { 00247 return tiles_view_; 00248 } 00249 00250 NUX_IMPLEMENT_OBJECT_TYPE(Tile); 00251 00252 Tile::Tile(NUX_FILE_LINE_DECL) 00253 : nux::TextureArea(NUX_FILE_LINE_PARAM) 00254 { 00255 fbo_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateFrameBufferObject(); 00256 texture_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(1, 1, 1, nux::BITFMT_R8G8B8A8); 00257 depth_texture_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(1, 1, 1, nux::BITFMT_D24S8); 00258 00259 fragment_shader_prog_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreatePixelShader(); 00260 vertex_shader_prog_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateVertexShader(); 00261 shader_prog_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateShaderProgram(); 00262 00263 vertex_shader_prog_->SetShaderCode(TCHAR_TO_ANSI(*tile_vertex_shader)); 00264 fragment_shader_prog_->SetShaderCode(TCHAR_TO_ANSI(*tile_fragment_shader)); 00265 00266 shader_prog_->ClearShaderObjects(); 00267 shader_prog_->AddShaderObject(vertex_shader_prog_); 00268 shader_prog_->AddShaderObject(fragment_shader_prog_); 00269 shader_prog_->Link(); 00270 00271 } 00272 00273 Tile::~Tile() 00274 { 00275 00276 } 00277 00278 void Tile::Draw(nux::GraphicsEngine &graphics_engine, bool force_draw) 00279 { 00280 int width = GetBaseWidth(); 00281 int height = GetBaseHeight(); 00282 00283 if ((texture_->GetWidth() != width) || (texture_->GetHeight() != height)) 00284 { 00285 texture_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(width, height, 1, nux::BITFMT_R8G8B8A8); 00286 } 00287 00288 if ((depth_texture_->GetWidth() != width) || (depth_texture_->GetHeight() != height)) 00289 { 00290 depth_texture_ = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(width, height, 1, nux::BITFMT_D24S8); 00291 } 00292 00293 //nux::ObjectPtr<nux::IOpenGLFrameBufferObject> prev_fbo = nux::GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); 00294 fbo_->FormatFrameBufferObject(width, height, nux::BITFMT_R8G8B8A8); 00295 fbo_->SetRenderTarget(0, texture_->GetSurfaceLevel(0)); 00296 fbo_->SetDepthSurface(depth_texture_->GetSurfaceLevel(0)); 00297 fbo_->Activate(); 00298 fbo_->EmptyClippingRegion(); 00299 nux::GetGraphicsDisplay()->GetGraphicsEngine()->SetContext(0, 0, width, height); 00300 nux::GetGraphicsDisplay()->GetGraphicsEngine()->SetViewport(0, 0, width, height); 00301 nux::GetGraphicsDisplay()->GetGraphicsEngine()->Push2DWindow(width, height); 00302 00303 nux::Geometry geo = GetAbsoluteGeometry(); 00304 00305 { 00306 nux::Color color = nux::color::RandomColor(); 00307 00308 float w = width; 00309 float h = height; 00310 float vertex_buffer[] = 00311 { 00312 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0, 0, color.red, color.green, color.blue, color.alpha, 00313 0.0f, h, 0.0f, 1.0f, 0.0f, 1.0f, 0, 0, color.red, color.green, color.blue, color.alpha, 00314 w, h, 0.0f, 1.0f, 1.0f, 1.0f, 0, 0, color.red, color.green, color.blue, color.alpha, 00315 w, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0, 0, color.red, color.green, color.blue, color.alpha, 00316 }; 00317 00318 CHECKGL(glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0)); 00319 CHECKGL(glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); 00320 shader_prog_->Begin(); 00321 00322 int texture_unit0_location = shader_prog_->GetUniformLocationARB("texture_unit0"); 00323 int vertex_attrib_location = shader_prog_->GetAttributeLocation("position"); 00324 int texture_coord_attrib_location = shader_prog_->GetAttributeLocation("texture"); 00325 int color_attrib_location = shader_prog_->GetAttributeLocation("color"); 00326 00327 if (texture_unit0_location != -1) 00328 { 00329 graphics_engine.SetTexture(GL_TEXTURE0, 0); 00330 CHECKGL(glUniform1iARB(texture_unit0_location, 0)); 00331 } 00332 00333 int mvp_matrix_location = shader_prog_->GetUniformLocationARB ("mvp_matrix"); 00334 nux::Matrix4 mvp_matrix = graphics_engine.GetOpenGLModelViewProjectionMatrix(); 00335 shader_prog_->SetUniformLocMatrix4fv((GLint) mvp_matrix_location, 1, false, (GLfloat *) &(mvp_matrix.m)); 00336 00337 CHECKGL(glEnableVertexAttribArrayARB(vertex_attrib_location)); 00338 CHECKGL(glVertexAttribPointerARB ( (GLuint) vertex_attrib_location, 4, GL_FLOAT, GL_FALSE, 48, vertex_buffer)); 00339 00340 if (texture_coord_attrib_location != -1) 00341 { 00342 CHECKGL ( glEnableVertexAttribArrayARB (texture_coord_attrib_location) ); 00343 CHECKGL ( glVertexAttribPointerARB ( (GLuint) texture_coord_attrib_location, 4, GL_FLOAT, GL_FALSE, 48, vertex_buffer + 4) ); 00344 } 00345 00346 if (color_attrib_location != -1) 00347 { 00348 CHECKGL ( glEnableVertexAttribArrayARB (color_attrib_location) ); 00349 CHECKGL ( glVertexAttribPointerARB ( (GLuint) color_attrib_location, 4, GL_FLOAT, GL_FALSE, 48, vertex_buffer + 8) ); 00350 } 00351 00352 CHECKGL ( glDrawArrays (GL_TRIANGLE_FAN, 0, 4) ); 00353 00354 CHECKGL ( glDisableVertexAttribArrayARB (vertex_attrib_location) ); 00355 00356 if (texture_coord_attrib_location != -1) 00357 CHECKGL ( glDisableVertexAttribArrayARB (texture_coord_attrib_location) ); 00358 00359 if (color_attrib_location != -1) 00360 CHECKGL ( glDisableVertexAttribArrayARB (color_attrib_location) ); 00361 00362 shader_prog_->End(); 00363 } 00364 00365 //nux::GetGraphicsDisplay()->GetGraphicsEngine()->QRP_Color(0, 0, geo.width, geo.height, nux::color::Aubergine); 00366 00367 nux::GetWindowCompositor().RestoreRenderingSurface(); 00368 00369 nux::TexCoordXForm texxform; 00370 nux::GetGraphicsDisplay()->GetGraphicsEngine()->QRP_1Tex(geo.x, geo.y, geo.width, geo.height, texture_, texxform, nux::color::White); 00371 //nux::TextureArea::Draw(graphics_engine, force_draw); 00372 } 00373 00374 00375 void ThreadWidgetInit(nux::NThread* thread, void* InitData) 00376 { 00377 nux::VLayout* MainVLayout = new nux::VLayout(NUX_TRACKER_LOCATION); 00378 00379 TileManager *tile_manager = new TileManager(); 00380 for (int i = 0; i < 10; i++) 00381 { 00382 tile_manager->CreateTile(); 00383 tile_manager->CreateTile(); 00384 tile_manager->CreateTile(); 00385 tile_manager->CreateTile(); 00386 tile_manager->CreateTile(); 00387 } 00388 00389 MainVLayout->AddView(tile_manager->GetTilesView(), 1, nux::eCenter, nux::MINOR_SIZE_FULL); 00390 MainVLayout->SetContentDistribution(nux::eStackCenter); 00391 00392 nux::GetWindowThread ()->SetLayout(MainVLayout); 00393 nux::ColorLayer background(nux::Color(0xFF4D4D4D)); 00394 static_cast<nux::WindowThread*>(thread)->SetWindowBackgroundPaintLayer(&background); 00395 } 00396 00397 nux::logging::Logger logger("test.tile_view"); 00398 int main(int argc, char **argv) 00399 { 00400 nux::NuxInitialize(0); 00401 00402 logger.SetLogLevel(nux::logging::Debug); 00403 LOG_DEBUG(logger) << "\nTest\n"; 00404 00405 nux::WindowThread* wt = nux::CreateGUIThread(TEXT("ScrollView"), 400, 300, 0, &ThreadWidgetInit, 0); 00406 wt->Run(NULL); 00407 00408 delete wt; 00409 return 0; 00410 }