nux-1.16.0
tiles_view.cpp
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 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends