wg_view.cpp

00001 // wg_view.cpp
00002 //
00003 // CView class implementation
00004 //
00005 //
00006 // Copyright (c) 2002-2004 Rob Wiskow
00007 // rob-dev@boxedchaos.com
00008 //
00009 // This library is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU Lesser General Public
00011 // License as published by the Free Software Foundation; either
00012 // version 2.1 of the License, or (at your option) any later version.
00013 //
00014 // This library is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00017 // Lesser General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU Lesser General Public
00020 // License along with this library; if not, write to the Free Software
00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00022 //
00023 
00024 
00025 #include "wgui_include_config.h"
00026 #include "wutil_debug.h"
00027 #include "wg_view.h"
00028 #include "wg_error.h"
00029 #include "wg_painter.h"
00030 #include "wg_message_server.h"
00031 #include "wg_application.h"
00032 #include "wg_frame.h"
00033 #include "std_ex.h"
00034 
00035 
00036 namespace wGui
00037 {
00038 
00039 CView* CView::m_pInstance = 0;
00040 
00041 
00042 CView::CView(const CRect& WindowRect, std::wstring sTitle, bool bResizable, bool bFullScreen) :
00043      CWindow(WindowRect, 0),
00044      m_bResizable(bResizable),
00045      m_bFullScreen(bFullScreen),
00046      m_pMenu(0),
00047      m_pFloatingWindow(0),
00048      m_pScreenSurface(0)
00049 {
00050      if (m_pInstance)
00051      {
00052           throw(Wg_Ex_App(L"Cannot have more than one view at a time!"));
00053      }
00054      m_pInstance = this;
00055 
00056      CMessageServer::Instance().RegisterMessageClient(this, CMessage::APP_PAINT);
00057      CMessageServer::Instance().RegisterMessageClient(this, CMessage::APP_DESTROY_FRAME, CMessageServer::PRIORITY_FIRST);
00058      CMessageServer::Instance().RegisterMessageClient(this, CMessage::CTRL_RESIZE);
00059      CMessageServer::Instance().RegisterMessageClient(this, CMessage::MOUSE_BUTTONDOWN, CMessageServer::PRIORITY_FIRST);
00060      CMessageServer::Instance().RegisterMessageClient(this, CMessage::MOUSE_BUTTONUP, CMessageServer::PRIORITY_FIRST);
00061 
00062      SetWindowRect(WindowRect);
00063      SetWindowText(sTitle);
00064      CApplication::Instance()->GetApplicationLog().AddLogEntry(L"Created new CView : " + sTitle, APP_LOG_INFO);
00065      Draw();
00066 }
00067 
00068 
00069 CView::~CView(void)
00070 {
00071      delete m_pMenu;
00072      if (m_pInstance == this)
00073      {
00074           m_pInstance = 0;
00075      }
00076 }
00077 
00078 
00079 void CView::AttachMenu(CMenu* pMenu)
00080 {
00081      delete m_pMenu;
00082      m_pMenu = pMenu;
00083      if (m_pMenu)
00084      {
00085           m_pMenu->SetNewParent(this);
00086           int iMenuHeight = m_pMenu->GetWindowRect().Height();
00087           m_pMenu->SetWindowRect(CRect(0, -iMenuHeight, m_WindowRect.Width() - 1, -1));
00088           m_ClientRect.SetTop(iMenuHeight + 1);
00089           m_ClientRect.ClipTo(m_WindowRect.SizeRect());
00090      }
00091      else
00092      {
00093           m_ClientRect = m_WindowRect.SizeRect();
00094      }
00095 }
00096 
00097 
00098 void CView::SetWindowText(const std::wstring& sText)
00099 {
00100      CWindow::SetWindowText(sText);
00101      SDL_WM_SetCaption(stdex::ToMbString(m_sWindowText).c_str(), "");
00102 }
00103 
00104 
00105 void CView::SetWindowRect(const CRect& WindowRect)
00106 {
00107      CWindow::SetWindowRect(WindowRect);
00108      m_ClientRect = CRect(0, 0, m_WindowRect.Width(), m_WindowRect.Height());
00109 
00110      Uint32 iFlags = SDL_SWSURFACE | SDL_ANYFORMAT ;
00111      if (m_bResizable && !m_bFullScreen)
00112      {
00113           iFlags |= SDL_RESIZABLE ;
00114      }
00115      if (m_bFullScreen)
00116      {
00117           iFlags |= SDL_FULLSCREEN ;
00118           m_bResizable = false;
00119      }
00120 
00121      m_pScreenSurface = SDL_SetVideoMode(m_WindowRect.Width(), m_WindowRect.Height(), CApplication::Instance()->GetBitsPerPixel(), iFlags);
00122      if (m_pScreenSurface == NULL)
00123           throw(Wg_Ex_SDL(std::wstring(L"Could not set video mode : ") + stdex::ToWString(SDL_GetError())) );
00124 }
00125 
00126 
00127 void CView::SwitchMode(const CRect& WindowRect, bool bResizable, bool bFullScreen)
00128 {
00129      m_bResizable = bResizable;
00130      m_bFullScreen = bFullScreen;
00131 
00132      SetWindowRect(WindowRect);
00133 }
00134 
00135 
00136 
00137 bool CView::HandleMessage(CMessage* pMessage)
00138 {
00139      bool bHandled = false;
00140 
00141      if (pMessage)
00142      {
00143           switch(pMessage->MessageType())
00144           {
00145           case CMessage::APP_PAINT :
00146                if (pMessage->Destination() == this || pMessage->Destination() == 0)
00147                {
00148                     SDL_Surface* pFloatingSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, m_WindowRect.Width(), m_WindowRect.Height(),
00149                          CApplication::Instance()->GetBitsPerPixel(), 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);
00150                     PaintToSurface(*m_pScreenSurface, *pFloatingSurface, CPoint(0, 0));
00151                     SDL_Rect SourceRect = CRect(m_WindowRect.SizeRect()).SDLRect();
00152                     SDL_Rect DestRect = CRect(m_WindowRect.SizeRect()).SDLRect();
00153                     SDL_BlitSurface(pFloatingSurface, &SourceRect, m_pScreenSurface, &DestRect);
00154                     SDL_FreeSurface(pFloatingSurface);
00155                     SDL_UpdateRect(m_pScreenSurface, 0, 0, 0, 0);
00156                     bHandled = true;
00157                }
00158                break;
00159           case CMessage::APP_DESTROY_FRAME:
00160                if (pMessage->Destination() == this || pMessage->Destination() == 0)
00161                {
00162                     CFrame* pFrame = dynamic_cast<CFrame*>(const_cast<CMessageClient*>(pMessage->Source()));
00163                     if (pFrame)
00164                     {
00165                          pFrame->SetNewParent(0);
00166                          CMessageServer::Instance().QueueMessage(new CMessage(CMessage::APP_PAINT, 0, this));
00167                          delete pFrame;
00168                     }
00169                     bHandled = true;
00170                }
00171                break;
00172           case CMessage::CTRL_RESIZE:
00173           {
00174                TPointMessage* pResizeMessage = dynamic_cast<TPointMessage*>(pMessage);
00175                if (pResizeMessage && pResizeMessage->Source() == CApplication::Instance())
00176                {
00177                     CWindow::SetWindowRect(CRect(m_WindowRect.TopLeft(), m_WindowRect.TopLeft() + pResizeMessage->Value()));
00178                     Uint32 iFlags = SDL_SWSURFACE | SDL_ANYFORMAT;
00179                     if(m_bResizable)
00180                     {
00181                          iFlags |= SDL_RESIZABLE;
00182                     }
00183 
00184                     m_ClientRect = CRect(m_ClientRect.Left(), m_ClientRect.Top(), m_WindowRect.Width(), m_WindowRect.Height());
00185                     m_ClientRect.ClipTo(m_WindowRect.SizeRect());
00186 
00187                     m_pScreenSurface = SDL_SetVideoMode(m_WindowRect.Width(), m_WindowRect.Height(), DEFAULT_BPP, iFlags);
00188                     if (m_pScreenSurface == NULL)
00189                          throw(Wg_Ex_SDL(std::wstring(L"Could not set video mode : ") + stdex::ToWString(SDL_GetError())) );
00190 
00191                     bHandled = true;
00192                }
00193                break;
00194           }
00195           case CMessage::MOUSE_BUTTONDOWN:
00196           {
00197                CMouseMessage* pMouseMessage = dynamic_cast<CMouseMessage*>(pMessage);
00198                if (pMouseMessage && m_WindowRect.HitTest(pMouseMessage->Point) == CRect::RELPOS_INSIDE)
00199                {
00200                     if (!m_pFloatingWindow || !m_pFloatingWindow->OnMouseButtonDown(pMouseMessage->Point, pMouseMessage->Button))
00201                     {
00202                          if (pMouseMessage->Destination() == 0)
00203                          {
00204                               OnMouseButtonDown(pMouseMessage->Point, pMouseMessage->Button);
00205                          }
00206                          else if (dynamic_cast<const CWindow*>(pMouseMessage->Destination()))
00207                          {
00208                               const_cast<CWindow*>(static_cast<const CWindow*>(pMouseMessage->Destination()))->
00209                                    OnMouseButtonDown(pMouseMessage->Point, pMouseMessage->Button);
00210                          }
00211                     }
00212                }
00213                break;
00214           }
00215           case CMessage::MOUSE_BUTTONUP:
00216           {
00217                CMouseMessage* pMouseMessage = dynamic_cast<CMouseMessage*>(pMessage);
00218                if (pMouseMessage && m_WindowRect.HitTest(pMouseMessage->Point) == CRect::RELPOS_INSIDE)
00219                {
00220                     if (!m_pFloatingWindow || !m_pFloatingWindow->OnMouseButtonUp(pMouseMessage->Point, pMouseMessage->Button))
00221                     {
00222                          if (pMouseMessage->Destination() == 0)
00223                          {
00224                               OnMouseButtonUp(pMouseMessage->Point, pMouseMessage->Button);
00225                          }
00226                          else if (dynamic_cast<const CWindow*>(pMouseMessage->Destination()))
00227                          {
00228                               const_cast<CWindow*>(static_cast<const CWindow*>(pMouseMessage->Destination()))->
00229                                    OnMouseButtonUp(pMouseMessage->Point, pMouseMessage->Button);
00230                          }
00231                     }
00232                }
00233                break;
00234           }
00235           default :
00236                bHandled = CWindow::HandleMessage(pMessage);
00237                break;
00238           }
00239      }
00240 
00241      return bHandled;
00242 }
00243 
00244 }
00245 
00246 

Generated on Wed May 16 23:11:26 2007 for wGui by  doxygen 1.5.1