00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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