nux-1.14.0
ClientArea.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 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 ()->GetWindow().HasFrameBufferSupport() )
00051     {
00052       m_FrameBufferObject = GetGraphicsDisplay()->GetGpuDevice()->CreateFrameBufferObject();
00053       m_MainColorRT = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture (2, 2, 1, BITFMT_R8G8B8A8);
00054       m_MainDepthRT = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture (2, 2, 1, BITFMT_D24S8);
00055     }
00056   }
00057 
00058   ClientArea::~ClientArea()
00059   {
00060   }
00061 
00062   long ClientArea::ProcessEvent (IEvent &ievent, long TraverseInfo, long ProcessEventInfo)
00063   {
00064     long ret = TraverseInfo;
00065 
00066 //     // A is obtained from GfxContext. So A dimension's are in relative window coordinates.
00067 //     Rect A = GetGraphicsDisplay()->GetGraphicsEngine()->GetClippingRegion();
00068 //     Rect B = Rect(GetBaseX(), GetBaseY(), GetBaseWidth(), GetBaseHeight());
00069 //     Rect C = A.intersect(B);
00070 //     if((ievent.e_event == NUX_MOUSE_MOVE) && !IsMouseOwner())
00071 //     {
00072 //         if(!C.IsPointInside(ievent.e_x, ievent.e_y))
00073 //             return ret;
00074 //     }
00075     ret = PostProcessEvent2 (ievent, ret, ProcessEventInfo);
00076     return ret;
00077   }
00078 
00079   void ClientArea::BeginDraw (GraphicsEngine &GfxContext, bool force_draw)
00080   {
00081     if ( (IsRedrawNeeded() == false) && (force_draw == false) )
00082       return;
00083 
00084     if (GetWindowThread ()->GetWindow().HasFrameBufferSupport() )
00085     {
00086       int buffer_width = GetBaseWidth();
00087       int buffer_height = GetBaseHeight();
00088       int window_width, window_height;
00089       window_width = GfxContext.GetViewportWidth ();
00090       window_height = GfxContext.GetViewportHeight ();
00091 
00092       m_ctx.x = GetBaseX();
00093       m_ctx.y = GetBaseY();
00094       m_ctx.width  = GetBaseWidth();
00095       m_ctx.height = GetBaseHeight();
00096 
00097       // A is obtained from GfxContext. So A dimension's are in relative window coordinates.
00098       Rect A = GfxContext.GetClippingRegion();
00099       Rect B = Rect (m_ctx.x, m_ctx.y, m_ctx.width, m_ctx.height);
00100       Rect C = A.Intersect (B);
00101 
00102       m_ctx.x_clipregion = C.x;
00103       m_ctx.y_clipregion = C.y;
00104       m_ctx.width_clipregion  = C.GetWidth();
00105       m_ctx.height_clipregion = C.GetHeight();
00106 
00107       ObjectPtr<IOpenGLFrameBufferObject> prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject();
00108 
00109       if ( (m_FrameBufferObject->GetWidth() != buffer_width) || (m_FrameBufferObject->GetHeight() != buffer_height) )
00110       {
00111         m_FrameBufferObject->FormatFrameBufferObject (buffer_width, buffer_height, BITFMT_R8G8B8A8);
00112         m_MainColorRT = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture (buffer_width, buffer_height, 1, BITFMT_R8G8B8A8);
00113         m_MainDepthRT = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture (buffer_width, buffer_height, 1, BITFMT_D24S8);
00114       }
00115 
00116       m_FrameBufferObject->SetRenderTarget (0, m_MainColorRT->GetSurfaceLevel (0) );
00117       m_FrameBufferObject->SetDepthSurface (m_MainDepthRT->GetSurfaceLevel (0) );
00118       m_FrameBufferObject->Activate();
00119 
00120       GfxContext.SetViewport (0, 0, buffer_width, buffer_height);
00121       m_FrameBufferObject->EmptyClippingRegion();
00122 
00123       ClientDraw (GfxContext, m_ctx, force_draw);
00124 
00125       // Restore the main frame buffer object
00126       prevFBO->Activate();
00127       GfxContext.SetViewport (0, 0, window_width, window_height);
00128       GfxContext.ApplyClippingRectangle();
00129       GfxContext.Push2DWindow (window_width, window_height);
00130 
00131       // Copy the client frame buffer into the main frame buffer.
00132       {
00133         t_u32 w, h;
00134         w = m_MainColorRT->GetWidth();
00135         h = m_MainColorRT->GetHeight();
00136         int x = m_ctx.x;
00137         int y = m_ctx.y;
00138 
00139         TexCoordXForm texxform0;
00140         texxform0.uwrap = TEXWRAP_CLAMP;
00141         texxform0.vwrap = TEXWRAP_CLAMP;
00142         texxform0.FlipVCoord (true);
00143         GetGraphicsDisplay()->GetGraphicsEngine()->QRP_1Tex (x, y, w, h, m_MainColorRT, texxform0, Color (color::White) );
00144       }
00145 
00146       // go back to 2D in case that was changed by the client.
00147       GfxContext.SetViewport (0, 0, window_width, window_height);
00148       GfxContext.ApplyClippingRectangle();
00149       GfxContext.Push2DWindow (window_width, window_height);
00150     }
00151     else
00152     {
00153       int x = GfxContext.GetContextX();
00154       int y = GfxContext.GetContextY();
00155 
00156       // The clientarea is in absolute window coordinates. It needs to be offset so that it is in relative window coordinates.
00157       m_ctx.x = GetBaseX() + x;
00158       m_ctx.y = GetBaseY() + y;
00159       m_ctx.width  = GetBaseWidth();
00160       m_ctx.height = GetBaseHeight();
00161 
00162       // A is obtained from GfxContext. So A dimension's are in relative window coordinates.
00163       Rect A = GfxContext.GetClippingRegion();
00164 
00165       Rect B = Rect (m_ctx.x, m_ctx.y, m_ctx.width, m_ctx.height);
00166       Rect C = A.Intersect (B);
00167 
00168       m_ctx.x_clipregion = C.x;
00169       m_ctx.y_clipregion = C.y;
00170       m_ctx.width_clipregion  = C.GetWidth();
00171       m_ctx.height_clipregion = C.GetHeight();
00172 
00173       int window_width, window_height;
00174       window_width = GfxContext.GetViewportWidth ();
00175       window_height = GfxContext.GetViewportHeight ();
00176 
00177       SetClientViewport (GfxContext);
00178 //         GfxContext.SetViewport(
00179 //             m_ctx.x, window_height - m_ctx.y - m_ctx.height, m_ctx.width, m_ctx.height);
00180 //
00181 //         GfxContext.SetOpenGLClippingRectangle(
00182 //             m_ctx.x_clipregion,
00183 //             window_height - m_ctx.y_clipregion - m_ctx.height_clipregion,
00184 //             m_ctx.width_clipregion,
00185 //             m_ctx.height_clipregion);
00186 
00187       ClientDraw (GfxContext, m_ctx, force_draw);
00188 
00189       // go back to 2D in case that was changed by the client.
00190       GfxContext.SetViewport (0, 0, window_width, window_height);
00191       GfxContext.ApplyClippingRectangle();
00192       GfxContext.Push2DWindow (window_width, window_height);
00193     }
00194   }
00195 
00196   void ClientArea::Draw (GraphicsEngine &GfxContext, bool force_draw)
00197   {
00198     // don't draw here or we risk drawing more than one time.
00199     //BeginDraw(GfxContext, force_draw);
00200   }
00201 
00202   void ClientArea::DrawContent (GraphicsEngine &GfxContext, bool force_draw)
00203   {
00204     BeginDraw (GfxContext, force_draw);
00205 
00206   }
00207   void ClientArea::PostDraw (GraphicsEngine &GfxContext, bool force_draw)
00208   {
00209     // don't draw here or we risk drawing more than one time.
00210     //BeginDraw(GfxContext, force_draw);
00211   }
00212 
00213   void ClientArea::ClientDraw (GraphicsEngine &GfxContext, DrawAreaContext &ctx, bool force_draw)
00214   {
00215     glClearColor (0, 0, 0, 1);
00216     glClear (GL_COLOR_BUFFER_BIT);
00217   }
00218 
00219   void ClientArea::SetClientViewport (GraphicsEngine &GfxContext)
00220   {
00221     if (GetWindowThread ()->GetWindow().HasFrameBufferSupport() )
00222     {
00223       GfxContext.SetViewport (0, 0, m_FrameBufferObject->GetWidth(), m_FrameBufferObject->GetHeight() );
00224       m_FrameBufferObject->EmptyClippingRegion();
00225     }
00226     else
00227     {
00228       int window_height = GfxContext.GetViewportHeight();
00229 
00230       GfxContext.SetViewport (
00231         m_ctx.x, window_height - m_ctx.y - m_ctx.height, m_ctx.width, m_ctx.height);
00232 
00233       GfxContext.SetOpenGLClippingRectangle (
00234         m_ctx.x_clipregion,
00235         window_height - m_ctx.y_clipregion - m_ctx.height_clipregion,
00236         m_ctx.width_clipregion,
00237         m_ctx.height_clipregion);
00238     }
00239   }
00240 
00241   void ClientArea::Setup2DMode (GraphicsEngine &GfxContext)
00242   {
00243     //Restore 2D ViewPort
00244     GfxContext.SetViewport (0, 0, GetBaseWidth(), GetBaseHeight() );
00245     GfxContext.Push2DWindow (GetBaseWidth(), GetBaseHeight() );
00246 
00247   }
00248 
00249 
00250   void ClientArea::RecvMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags)
00251   {
00252 
00253   }
00254 
00255   void ClientArea::RecvMouseUp (int x, int y, unsigned long button_flags, unsigned long key_flags)
00256   {
00257 
00258   }
00259 
00260   void ClientArea::RecvMouseDrag (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)
00261   {
00262 
00263   }
00264 
00265   void ClientArea::RecvMouseMove (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)
00266   {
00267 
00268   }
00269 
00270   void ClientArea::RecvKeyEvent (
00271     unsigned long     event_type,    /*event type*/
00272     unsigned long     GetKeySym,    /*event keysym*/
00273     unsigned long     event_state,    /*event state*/
00274     const TCHAR*      event_char,    /*character*/
00275     unsigned short    repeat_count     /*key repeat count*/
00276   )
00277   {
00278 
00279   }
00280 
00281   void ClientArea::QueueDraw()
00282   {
00283     //GetWindowCompositor()..AddToDrawList(this);
00284     WindowThread* application = GetWindowThread ();
00285     if(application)
00286     {
00287       application->AddToDrawList(this);
00288       application->RequestRedraw();
00289       //GetWindowCompositor().AddToDrawList(this);
00290     }
00291     _need_redraw = true;
00292   }
00293 
00294   bool ClientArea::AcceptKeyNavFocus()
00295   {
00296     return false;
00297   }
00298 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends