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 "wg_window.h"
00027 #include "std_ex.h"
00028 #include "wg_painter.h"
00029 #include "wg_application.h"
00030 #include "wg_error.h"
00031 #include "wutil_debug.h"
00032 #include "wg_message_server.h"
00033 #include "wg_view.h"
00034 #include <algorithm>
00035
00036
00037 namespace wGui
00038 {
00039
00040 CWindow::CWindow(const CRect& WindowRect, CWindow* pParent) :
00041 m_sWindowText(L""),
00042 m_WindowRect(WindowRect),
00043 m_BackgroundColor(DEFAULT_BACKGROUND_COLOR),
00044 m_ClientRect(WindowRect.SizeRect()),
00045 m_pParentWindow(0),
00046 m_pSDLSurface(0),
00047 m_bVisible(true)
00048 {
00049 if (!CApplication::Instance())
00050 {
00051 throw(Wg_Ex_App(L"CWindow Constructor: No Application instance!"));
00052 }
00053
00054 SetWindowRect(WindowRect);
00055 m_BackgroundColor = CApplication::Instance()->GetDefaultBackgroundColor();
00056 SetNewParent(pParent);
00057 }
00058
00059
00060 CWindow::~CWindow(void)
00061 {
00062
00063 CMessageServer::Instance().DeregisterMessageClient(this);
00064
00065 if (m_pSDLSurface)
00066 SDL_FreeSurface(m_pSDLSurface);
00067 while (m_ChildWindows.size() > 0)
00068 {
00069 delete *(m_ChildWindows.begin());
00070 }
00071 m_ChildWindows.clear();
00072 SetNewParent(0);
00073 }
00074
00075
00076 void CWindow::SetWindowRect(const CRect& WindowRect)
00077 {
00078 double dHorizontalScale = m_WindowRect.Width() != 0 ? static_cast<double>(WindowRect.Width()) / m_WindowRect.Width() : 0;
00079 double dVerticalScale = m_WindowRect.Height() != 0 ? static_cast<double>(WindowRect.Height()) / m_WindowRect.Height() : 0;
00080 m_WindowRect = WindowRect;
00081 if (m_pSDLSurface)
00082 SDL_FreeSurface(m_pSDLSurface);
00083 m_pSDLSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, m_WindowRect.Width(), m_WindowRect.Height(),
00084 CApplication::Instance()->GetBitsPerPixel(), 0x000000FF, 0x0000FF00, 0x00FF0000, 0);
00085 if (!m_pSDLSurface)
00086 {
00087 CApplication::Instance()->GetApplicationLog().AddLogEntry(std::wstring(L"SDL Unable To Create Surface: ") + stdex::ToWString(SDL_GetError()), APP_LOG_ERROR);
00088 }
00089 m_ClientRect = CRect(stdex::safe_static_cast<int>(m_ClientRect.Left() * dHorizontalScale), stdex::safe_static_cast<int>(m_ClientRect.Top() * dVerticalScale),
00090 stdex::safe_static_cast<int>(m_ClientRect.Right() * dHorizontalScale), stdex::safe_static_cast<int>(m_ClientRect.Bottom() * dVerticalScale));
00091 Draw();
00092 }
00093
00094
00095 void CWindow::MoveWindow(const CPoint& MoveDistance)
00096 {
00097 m_WindowRect = m_WindowRect + MoveDistance;
00098 CMessageServer::Instance().QueueMessage(new CMessage(CMessage::APP_PAINT, 0, this));
00099 }
00100
00101
00102 CWindow* CWindow::GetAncestor(EAncestor eAncestor) const
00103 {
00104 CWindow* pWindow = 0;
00105
00106 switch (eAncestor)
00107 {
00108 case PARENT:
00109 pWindow = m_pParentWindow;
00110 break;
00111 case ROOT:
00112 pWindow = m_pParentWindow;
00113 if (pWindow)
00114 {
00115 while (pWindow->m_pParentWindow)
00116 {
00117 pWindow = pWindow->m_pParentWindow;
00118 }
00119 }
00120 else
00121 {
00122 pWindow = const_cast<CWindow*>(this);
00123 }
00124 break;
00125 }
00126
00127 return pWindow;
00128 }
00129
00130
00131 CView* CWindow::GetView(void) const
00132 {
00133 return dynamic_cast<CView*>(GetAncestor(ROOT));
00134 }
00135
00136
00137 bool CWindow::IsChildOf(CWindow* pWindow) const
00138 {
00139 const CWindow* pCurrentWindow = this;
00140 bool bIsChild = false;
00141
00142 while (!bIsChild && pCurrentWindow)
00143 {
00144 pCurrentWindow = pCurrentWindow->GetAncestor(PARENT);
00145 if (pCurrentWindow == pWindow)
00146 {
00147 bIsChild = true;
00148 }
00149 }
00150
00151 return bIsChild;
00152 }
00153
00154
00155 void CWindow::SetVisible(bool bVisible)
00156 {
00157 if (m_bVisible != bVisible)
00158 {
00159 m_bVisible = bVisible;
00160 for (std::list<CWindow*>::const_iterator iter = m_ChildWindows.begin(); iter != m_ChildWindows.end(); ++iter)
00161 {
00162 (*iter)->SetVisible(bVisible);
00163 if (!bVisible && (*iter) == CApplication::Instance()->GetKeyFocus())
00164 {
00165 CApplication::Instance()->SetKeyFocus(0);
00166 }
00167 }
00168 CMessageServer::Instance().QueueMessage(new CMessage(CMessage::APP_PAINT, 0, this));
00169 }
00170 }
00171
00172
00173 CRect CWindow::ClientToView(const CRect& Rect) const
00174 {
00175 CRect ScreenRect(Rect + m_ClientRect.TopLeft() + m_WindowRect.TopLeft());
00176 if (m_pParentWindow)
00177 {
00178 ScreenRect = m_pParentWindow->ClientToView(ScreenRect);
00179 }
00180 return ScreenRect;
00181 }
00182
00183
00184 CPoint CWindow::ClientToView(const CPoint& Point) const
00185 {
00186 CPoint ScreenPoint(Point + m_ClientRect.TopLeft() + m_WindowRect.TopLeft());
00187 if (m_pParentWindow)
00188 {
00189 ScreenPoint = m_pParentWindow->ClientToView(ScreenPoint);
00190 }
00191 return ScreenPoint;
00192 }
00193
00194
00195 CRect CWindow::ViewToClient(const CRect& Rect) const
00196 {
00197 CRect WindowRect(Rect - m_WindowRect.TopLeft() - m_ClientRect.TopLeft());
00198 if (m_pParentWindow)
00199 {
00200 WindowRect = m_pParentWindow->ViewToClient(WindowRect);
00201 }
00202 return WindowRect;
00203 }
00204
00205
00206 CPoint CWindow::ViewToClient(const CPoint& Point) const
00207 {
00208 CPoint WindowPoint(Point - m_WindowRect.TopLeft() - m_ClientRect.TopLeft());
00209 if (m_pParentWindow)
00210 {
00211 WindowPoint = m_pParentWindow->ViewToClient(WindowPoint);
00212 }
00213 return WindowPoint;
00214 }
00215
00216
00217 CRect CWindow::ViewToWindow(const CRect& Rect) const
00218 {
00219 CRect WindowRect(Rect - m_WindowRect.TopLeft());
00220 if (m_pParentWindow)
00221 {
00222 WindowRect = m_pParentWindow->ViewToClient(WindowRect);
00223 }
00224 return WindowRect;
00225 }
00226
00227
00228 CPoint CWindow::ViewToWindow(const CPoint& Point) const
00229 {
00230 CPoint WindowPoint(Point - m_WindowRect.TopLeft());
00231 if (m_pParentWindow)
00232 {
00233 WindowPoint = m_pParentWindow->ViewToClient(WindowPoint);
00234 }
00235 return WindowPoint;
00236 }
00237
00238
00239 void CWindow::SetWindowText(const std::wstring& sText)
00240 {
00241 m_sWindowText = sText;
00242 Draw();
00243 }
00244
00245
00246 bool CWindow::HitTest(const CPoint& Point) const
00247 {
00248 bool bHit = m_WindowRect.SizeRect().HitTest(ViewToWindow(Point)) == CRect::RELPOS_INSIDE;
00249 for (std::list<CWindow*>::const_iterator iter = m_ChildWindows.begin(); !bHit && iter != m_ChildWindows.end(); ++iter)
00250 {
00251 bHit = (*iter)->HitTest(Point);
00252 }
00253 return bHit;
00254 }
00255
00256
00257 void CWindow::Draw(void) const
00258 {
00259 if (m_pSDLSurface)
00260 {
00261 CPainter Painter(m_pSDLSurface, CPainter::PAINT_REPLACE);
00262 Painter.DrawRect(m_WindowRect.SizeRect(), true, m_BackgroundColor, m_BackgroundColor);
00263 CMessageServer::Instance().QueueMessage(new CMessage(CMessage::APP_PAINT, 0, this));
00264 }
00265 }
00266
00267
00268 void CWindow::PaintToSurface(SDL_Surface& ScreenSurface, SDL_Surface& FloatingSurface, const CPoint& Offset) const
00269 {
00270 if (m_bVisible)
00271 {
00272 SDL_Rect SourceRect = CRect(m_WindowRect.SizeRect()).SDLRect();
00273 SDL_Rect DestRect = CRect(m_WindowRect + Offset).SDLRect();
00274 SDL_BlitSurface(m_pSDLSurface, &SourceRect, &ScreenSurface, &DestRect);
00275 CPoint NewOffset = m_ClientRect.TopLeft() + m_WindowRect.TopLeft() + Offset;
00276 for (std::list<CWindow*>::const_iterator iter = m_ChildWindows.begin(); iter != m_ChildWindows.end(); ++iter)
00277 {
00278 if (*iter)
00279 {
00280 (*iter)->PaintToSurface(ScreenSurface, FloatingSurface, NewOffset);
00281 }
00282 }
00283 }
00284 }
00285
00286
00287 void CWindow::SetNewParent(CWindow* pNewParent)
00288 {
00289 if (m_pParentWindow)
00290 {
00291 m_pParentWindow->DeregisterChildWindow(this);
00292 }
00293 if (pNewParent)
00294 {
00295 pNewParent->RegisterChildWindow(this);
00296 }
00297 m_pParentWindow = pNewParent;
00298 }
00299
00300
00301 bool CWindow::OnMouseButtonDown(CPoint Point, unsigned int Button)
00302 {
00303 bool bResult = false;
00304
00305 if (m_bVisible && (m_WindowRect.SizeRect().HitTest(ViewToWindow(Point)) == CRect::RELPOS_INSIDE))
00306 {
00307 for (std::list<CWindow*>::reverse_iterator iter = m_ChildWindows.rbegin(); iter != m_ChildWindows.rend(); ++iter)
00308 {
00309 bResult = (*iter)->OnMouseButtonDown(Point, Button);
00310 if (bResult)
00311 {
00312 break;
00313 }
00314 }
00315 }
00316
00317 return bResult;
00318 }
00319
00320
00321 bool CWindow::OnMouseButtonUp(CPoint Point, unsigned int Button)
00322 {
00323 bool bResult = false;
00324
00325 if (m_bVisible && (m_WindowRect.SizeRect().HitTest(ViewToWindow(Point)) == CRect::RELPOS_INSIDE))
00326 {
00327 for (std::list<CWindow*>::reverse_iterator iter = m_ChildWindows.rbegin(); iter != m_ChildWindows.rend(); ++iter)
00328 {
00329 bResult = (*iter)->OnMouseButtonUp(Point, Button);
00330 if (bResult)
00331 {
00332 break;
00333 }
00334 }
00335 }
00336
00337 return bResult;
00338 }
00339
00340
00341 void CWindow::RegisterChildWindow(CWindow* pWindow)
00342 {
00343 if (!pWindow)
00344 {
00345
00346 CApplication::Instance()->GetApplicationLog().AddLogEntry(
00347 L"CWindow::RegisterChildWindow : Attempting to register a non-existent child window.", APP_LOG_ERROR);
00348 }
00349 else
00350 {
00351 m_ChildWindows.push_back(pWindow);
00352 }
00353 }
00354
00355
00356 void CWindow::DeregisterChildWindow(CWindow* pWindow)
00357 {
00358 m_ChildWindows.remove(pWindow);
00359 }
00360
00361
00362 bool CWindow::HandleMessage(CMessage* )
00363 {
00364 bool bHandled = false;
00365
00366 return bHandled;
00367 }
00368
00369 }
00370