Back to index

nux  3.0.0
ClientArea.cpp
Go to the documentation of this file.
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 Lesser General Public License, as
00006  * published by the  Free Software Foundation; either version 2.1 or 3.0
00007  * of the License.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranties of
00011  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00012  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00013  * License for more details.
00014  *
00015  * You should have received a copy of both the GNU Lesser General Public
00016  * License along with this program. If not, see <http://www.gnu.org/licenses/>
00017  *
00018  * Authored by: Jay Taoko <jaytaoko@inalogic.com>
00019  *
00020  */
00021 
00022 
00023 #include "Nux.h"
00024 
00025 #if defined(NUX_OS_WINDOWS)
00026   #include "NuxGraphics/GraphicsDisplay.h"
00027 #elif defined(NUX_OS_LINUX)
00028   #include "NuxGraphics/GraphicsDisplay.h"
00029 #endif
00030 
00031 #include "NuxGraphics/GraphicsEngine.h"
00032 #include "TimerProc.h"
00033 #include "ClientArea.h"
00034 
00035 namespace nux
00036 {
00037 
00038   ClientArea::ClientArea(NUX_FILE_LINE_DECL)
00039     :   View(NUX_FILE_LINE_PARAM)
00040   {
00041     m_IsClientAreaEnabled = false;
00042     SetMinimumSize(DEFAULT_WIDGET_WIDTH, 4 * PRACTICAL_WIDGET_HEIGHT);
00043 
00044     mouse_down.connect(sigc::mem_fun(this, &ClientArea::RecvMouseDown));
00045     mouse_up.connect(sigc::mem_fun(this, &ClientArea::RecvMouseUp));
00046     mouse_drag.connect(sigc::mem_fun(this, &ClientArea::RecvMouseDrag));
00047     mouse_move.connect(sigc::mem_fun(this, &ClientArea::RecvMouseMove));
00048     key_down.connect(sigc::mem_fun(this, &ClientArea::RecvKeyEvent));
00049 
00050     if (GetWindowThread()->GetGraphicsDisplay().HasFrameBufferSupport())
00051     {
00052       m_FrameBufferObject = GetGraphicsDisplay()->GetGpuDevice()->CreateFrameBufferObject();
00053       m_MainColorRT = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(2, 2, 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION);
00054       m_MainDepthRT = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(2, 2, 1, BITFMT_D24S8, NUX_TRACKER_LOCATION);
00055     }
00056   }
00057 
00058   ClientArea::~ClientArea()
00059   {
00060   }
00061 
00062   void ClientArea::BeginDraw(GraphicsEngine &graphics_engine, bool force_draw)
00063   {
00064     if ((IsRedrawNeeded() == false) && (force_draw == false))
00065       return;
00066 
00067     if (GetWindowThread()->GetGraphicsDisplay().HasFrameBufferSupport())
00068     {
00069       int buffer_width = GetBaseWidth();
00070       int buffer_height = GetBaseHeight();
00071       int window_width, window_height;
00072       window_width = graphics_engine.GetViewportWidth();
00073       window_height = graphics_engine.GetViewportHeight();
00074 
00075       m_ctx.x = GetBaseX();
00076       m_ctx.y = GetBaseY();
00077       m_ctx.width  = GetBaseWidth();
00078       m_ctx.height = GetBaseHeight();
00079 
00080       // A is obtained from graphics_engine. So A dimension's are in relative window coordinates.
00081       Rect A = graphics_engine.GetClippingRegion();
00082       Rect B = Rect(m_ctx.x, m_ctx.y, m_ctx.width, m_ctx.height);
00083       Rect C = A.Intersect(B);
00084 
00085       m_ctx.x_clipregion = C.x;
00086       m_ctx.y_clipregion = C.y;
00087       m_ctx.width_clipregion  = C.GetWidth();
00088       m_ctx.height_clipregion = C.GetHeight();
00089 
00090       ObjectPtr<IOpenGLFrameBufferObject> prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject();
00091 
00092       if ((m_FrameBufferObject->GetWidth() != buffer_width) || (m_FrameBufferObject->GetHeight() != buffer_height))
00093       {
00094         m_FrameBufferObject->FormatFrameBufferObject(buffer_width, buffer_height, BITFMT_R8G8B8A8);
00095         m_MainColorRT = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(buffer_width, buffer_height, 1, BITFMT_R8G8B8A8, NUX_TRACKER_LOCATION);
00096         m_MainDepthRT = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(buffer_width, buffer_height, 1, BITFMT_D24S8, NUX_TRACKER_LOCATION);
00097       }
00098 
00099       m_FrameBufferObject->SetRenderTarget(0, m_MainColorRT->GetSurfaceLevel(0));
00100       m_FrameBufferObject->SetDepthSurface(m_MainDepthRT->GetSurfaceLevel(0));
00101       m_FrameBufferObject->Activate();
00102 
00103       graphics_engine.SetViewport(0, 0, buffer_width, buffer_height);
00104       m_FrameBufferObject->EmptyClippingRegion();
00105 
00106       ClientDraw(graphics_engine, m_ctx, force_draw);
00107 
00108       // Restore the main frame buffer object
00109       prevFBO->Activate();
00110 
00111       Area* view_window = GetTopLevelViewWindow();
00112       if (view_window)
00113       {
00114         graphics_engine.SetViewport(0, 0, view_window->GetBaseWidth(), view_window->GetBaseHeight());
00115         graphics_engine.ApplyClippingRectangle();
00116         graphics_engine.ApplyModelViewMatrix();
00117         graphics_engine.SetOrthographicProjectionMatrix(view_window->GetBaseWidth(), view_window->GetBaseHeight());
00118 
00119       }
00120       else
00121       {
00122         graphics_engine.SetViewport(0, 0, window_width, window_height);
00123         graphics_engine.ApplyClippingRectangle();
00124         graphics_engine.ApplyModelViewMatrix();
00125         graphics_engine.SetOrthographicProjectionMatrix(window_width, window_height);
00126       }
00127             
00128       // Copy the client frame buffer into the main frame buffer.
00129       {
00130         unsigned int w, h;
00131         w = m_MainColorRT->GetWidth();
00132         h = m_MainColorRT->GetHeight();
00133         int x = m_ctx.x;
00134         int y = m_ctx.y;
00135 
00136         TexCoordXForm texxform0;
00137         texxform0.uwrap = TEXWRAP_CLAMP;
00138         texxform0.vwrap = TEXWRAP_CLAMP;
00139         texxform0.FlipVCoord(true);
00140         GetGraphicsDisplay()->GetGraphicsEngine()->QRP_1Tex(x, y, w, h, m_MainColorRT, texxform0, Color(color::White));
00141       }
00142     }
00143     else
00144     {
00145       int x = graphics_engine.GetContextX();
00146       int y = graphics_engine.GetContextY();
00147 
00148       // The clientarea is in absolute window coordinates. It needs to be offset so that it is in relative window coordinates.
00149       m_ctx.x = GetBaseX() + x;
00150       m_ctx.y = GetBaseY() + y;
00151       m_ctx.width  = GetBaseWidth();
00152       m_ctx.height = GetBaseHeight();
00153 
00154       // A is obtained from graphics_engine. So A dimension's are in relative window coordinates.
00155       Rect A = graphics_engine.GetClippingRegion();
00156 
00157       Rect B = Rect(m_ctx.x, m_ctx.y, m_ctx.width, m_ctx.height);
00158       Rect C = A.Intersect(B);
00159 
00160       m_ctx.x_clipregion = C.x;
00161       m_ctx.y_clipregion = C.y;
00162       m_ctx.width_clipregion  = C.GetWidth();
00163       m_ctx.height_clipregion = C.GetHeight();
00164 
00165       int window_width, window_height;
00166       window_width = graphics_engine.GetViewportWidth();
00167       window_height = graphics_engine.GetViewportHeight();
00168 
00169       SetClientViewport(graphics_engine);
00170 //         graphics_engine.SetViewport(
00171 //             m_ctx.x, window_height - m_ctx.y - m_ctx.height, m_ctx.width, m_ctx.height);
00172 //
00173 //         graphics_engine.SetOpenGLClippingRectangle(
00174 //             m_ctx.x_clipregion,
00175 //             window_height - m_ctx.y_clipregion - m_ctx.height_clipregion,
00176 //             m_ctx.width_clipregion,
00177 //             m_ctx.height_clipregion);
00178 
00179       ClientDraw(graphics_engine, m_ctx, force_draw);
00180 
00181       // go back to 2D in case that was changed by the client.
00182       graphics_engine.SetViewport(0, 0, window_width, window_height);
00183       graphics_engine.ApplyClippingRectangle();
00184       graphics_engine.Push2DWindow(window_width, window_height);
00185     }
00186   }
00187 
00188   void ClientArea::Draw(GraphicsEngine &graphics_engine, bool force_draw)
00189   {
00190     // don't draw here or we risk drawing more than one time.
00191     //BeginDraw(graphics_engine, force_draw);
00192   }
00193 
00194   void ClientArea::DrawContent(GraphicsEngine &graphics_engine, bool force_draw)
00195   {
00196     BeginDraw(graphics_engine, force_draw);
00197 
00198   }
00199   void ClientArea::PostDraw(GraphicsEngine &graphics_engine, bool force_draw)
00200   {
00201     // don't draw here or we risk drawing more than one time.
00202     //BeginDraw(graphics_engine, force_draw);
00203   }
00204 
00205   void ClientArea::ClientDraw(GraphicsEngine &graphics_engine, DrawAreaContext &ctx, bool force_draw)
00206   {
00207     glClearColor(0, 0, 0, 1);
00208     glClear(GL_COLOR_BUFFER_BIT);
00209   }
00210 
00211   void ClientArea::SetClientViewport(GraphicsEngine &graphics_engine)
00212   {
00213     if (GetWindowThread()->GetGraphicsDisplay().HasFrameBufferSupport())
00214     {
00215       graphics_engine.SetViewport(0, 0, m_FrameBufferObject->GetWidth(), m_FrameBufferObject->GetHeight());
00216       m_FrameBufferObject->EmptyClippingRegion();
00217     }
00218     else
00219     {
00220       int window_height = graphics_engine.GetViewportHeight();
00221 
00222       graphics_engine.SetViewport(
00223         m_ctx.x, window_height - m_ctx.y - m_ctx.height, m_ctx.width, m_ctx.height);
00224 
00225       graphics_engine.SetOpenGLClippingRectangle(
00226         m_ctx.x_clipregion,
00227         window_height - m_ctx.y_clipregion - m_ctx.height_clipregion,
00228         m_ctx.width_clipregion,
00229         m_ctx.height_clipregion);
00230     }
00231   }
00232 
00233   void ClientArea::Setup2DMode(GraphicsEngine &graphics_engine)
00234   {
00235     //Restore 2D ViewPort
00236     graphics_engine.SetViewport(0, 0, GetBaseWidth(), GetBaseHeight());
00237     graphics_engine.Push2DWindow(GetBaseWidth(), GetBaseHeight());
00238 
00239   }
00240 
00241 
00242   void ClientArea::RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags)
00243   {
00244 
00245   }
00246 
00247   void ClientArea::RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags)
00248   {
00249 
00250   }
00251 
00252   void ClientArea::RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)
00253   {
00254 
00255   }
00256 
00257   void ClientArea::RecvMouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)
00258   {
00259 
00260   }
00261 
00262   void ClientArea::RecvKeyEvent(
00263     unsigned long     event_type,    /*event type*/
00264     unsigned long     GetKeySym,    /*event keysym*/
00265     unsigned long     event_state,    /*event state*/
00266     const char*      event_char,    /*character*/
00267     unsigned short    repeat_count     /*key repeat count*/
00268   )
00269   {
00270 
00271   }
00272 
00273   void ClientArea::QueueDraw()
00274   {
00275     //GetWindowCompositor()..AddToDrawList(this);
00276     WindowThread* application = GetWindowThread();
00277     if (application)
00278     {
00279       application->AddToDrawList(this);
00280       application->RequestRedraw();
00281       //GetWindowCompositor().AddToDrawList(this);
00282     }
00283     draw_cmd_queued_ = true;
00284   }
00285 
00286   bool ClientArea::AcceptKeyNavFocus()
00287   {
00288     return false;
00289   }
00290 }