wg_frame.cpp

00001 // wg_frame.cpp
00002 //
00003 // CFrame 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 "wg_frame.h"
00027 #include "wg_application.h"
00028 
00029 namespace wGui
00030 {
00031 
00032 CFrame::CFrame(const CRect& WindowRect, CView* pParent, CFontEngine* pFontEngine, const std::wstring& sTitle, bool bResizable) :
00033      CWindow(WindowRect, pParent),
00034      m_TitleBarColor(COLOR_BLUE),
00035      m_TitleBarTextColor(DEFAULT_LINE_COLOR),
00036      m_iTitleBarHeight(16),
00037      m_bResizable(bResizable),
00038      m_bModal(false),
00039      m_pMenu(0),
00040      m_bDragMode(false)
00041 {
00042      if (pFontEngine)
00043      {
00044           m_pFontEngine = pFontEngine;
00045      }
00046      else
00047      {
00048           m_pFontEngine = CApplication::Instance()->GetDefaultFontEngine();
00049      }
00050 
00051      m_sWindowText = sTitle;
00052      m_pFrameCloseButton = new CPictureButton(CRect(0, 0, 12, 12),
00053                this, CwgBitmapResourceHandle(WGRES_X_BITMAP));
00054 
00055      std::auto_ptr<CRenderedString> pRenderedString(new CRenderedString(m_pFontEngine, m_sWindowText, CRenderedString::VALIGN_CENTER));
00056      m_pRenderedString = pRenderedString;
00057 
00058      SetWindowRect(WindowRect);  // must be done after the buttons are created, and after the CRenderedString is created
00059 
00060      CMessageServer::Instance().RegisterMessageClient(this, CMessage::MOUSE_BUTTONUP);
00061      CMessageServer::Instance().RegisterMessageClient(this, CMessage::MOUSE_MOVE);
00062      CMessageServer::Instance().RegisterMessageClient(this, CMessage::CTRL_SINGLELCLICK);
00063 }
00064 
00065 
00066  CFrame::~CFrame(void)  // virtual
00067 {
00068      if (m_bModal)
00069      {
00070           SetModal(false);
00071      }
00072 }
00073 
00074 
00075 void CFrame::CloseFrame(void)
00076 {
00077      CMessageServer::Instance().QueueMessage(new CMessage(CMessage::APP_DESTROY_FRAME, 0, this));
00078 }
00079 
00080 
00081 void CFrame::SetModal(bool bModal)
00082 {
00083      m_bModal = bModal;
00084      
00085      if (m_bModal)
00086      {
00087           CApplication::Instance()->SetMouseFocus(this);
00088           CApplication::Instance()->SetKeyFocus(this);
00089      }
00090      else
00091      {
00092           CApplication::Instance()->SetMouseFocus(m_pParentWindow);
00093           CApplication::Instance()->SetKeyFocus(m_pParentWindow);
00094      }
00095 }
00096 
00097 
00098 void CFrame::Draw(void) const  // virtual
00099 {
00100      CWindow::Draw();
00101 
00102      if (m_pSDLSurface)
00103      {
00104           CPainter Painter(m_pSDLSurface, CPainter::PAINT_REPLACE);
00105           CRect SubRect(m_WindowRect.SizeRect());
00106           SubRect.Grow(-1);
00107           Painter.DrawRect(SubRect, false, COLOR_LIGHTGRAY);
00108           Painter.DrawHLine(0, SubRect.Width(), SubRect.Height(), COLOR_DARKGRAY);
00109           Painter.DrawVLine(0, SubRect.Height(), SubRect.Width(), COLOR_DARKGRAY);
00110           SubRect.Grow(-1);
00111           Painter.DrawRect(SubRect, false, COLOR_BLACK);
00112           Painter.DrawRect(m_TitleBarRect, true, m_TitleBarColor, m_TitleBarColor);
00113 
00114           CRect TextClipRect(m_TitleBarRect);
00115           TextClipRect.SetRight(TextClipRect.Right() - 16);
00116           TextClipRect.Grow(-1);
00117           if (m_pRenderedString.get())
00118           {
00119                m_pRenderedString->Draw(m_pSDLSurface, TextClipRect, m_TitleBarRect.TopLeft() + CPoint(6, m_iTitleBarHeight / 2), m_TitleBarTextColor);
00120           }
00121      }
00122 }
00123 
00124 
00125 void CFrame::PaintToSurface(SDL_Surface& ScreenSurface, SDL_Surface& FloatingSurface, const CPoint& Offset) const
00126 {
00127      if (m_bVisible)
00128      {
00129           SDL_Rect SourceRect = CRect(m_WindowRect.SizeRect()).SDLRect();
00130           if (!m_bDragMode)
00131           {
00132                SDL_Rect DestRect = CRect(m_WindowRect + Offset).SDLRect();
00133                SDL_BlitSurface(m_pSDLSurface, &SourceRect, &ScreenSurface, &DestRect);
00134                CPoint NewOffset = m_ClientRect.TopLeft() + m_WindowRect.TopLeft() + Offset;
00135                for (std::list<CWindow*>::const_iterator iter = m_ChildWindows.begin(); iter != m_ChildWindows.end(); ++iter)
00136                {
00137                     if (*iter)
00138                     {
00139                          (*iter)->PaintToSurface(ScreenSurface, FloatingSurface, NewOffset);
00140                     }
00141                }
00142           }    
00143           else
00144           {
00145                SDL_Rect DestGhostRect = CRect(m_FrameGhostRect + Offset).SDLRect();
00146                SDL_BlitSurface(m_pSDLSurface, &SourceRect, &FloatingSurface, &DestGhostRect);
00147                for (std::list<CWindow*>::const_iterator iter = m_ChildWindows.begin(); iter != m_ChildWindows.end(); ++iter)
00148                {
00149                     if (*iter)
00150                     {
00151                          (*iter)->PaintToSurface(FloatingSurface, FloatingSurface, m_ClientRect.TopLeft() + m_FrameGhostRect.TopLeft() + Offset);
00152                     }
00153                }
00154 //             // this is a quick trick to convert the surface to being semi-transparent
00155 // this is temporarily disabled due to it causing a crash when the frame extends beyond the borders of the parent view
00156 //             CPainter Painter(&FloatingSurface, CPainter::PAINT_AND);
00157 //             Painter.DrawRect(m_FrameGhostRect + Offset, true, CRGBColor(0xFF, 0xFF, 0xFF, 0x80), CRGBColor(0xFF, 0xFF, 0xFF, 0x80));
00158           }
00159      }
00160 }
00161 
00162 
00163 void CFrame::SetTitleBarHeight(int iTitleBarHeight)
00164 {
00165      m_iTitleBarHeight = iTitleBarHeight;
00166      SetWindowRect(m_WindowRect);
00167 }
00168 
00169 
00170 void CFrame::AttachMenu(CMenu* pMenu)
00171 {
00172      delete m_pMenu;
00173      m_pMenu = pMenu;
00174      if (m_pMenu)
00175      {
00176           int iMenuHeight = m_pMenu->GetWindowRect().Height();
00177           m_pMenu->SetWindowRect(CRect(0, -iMenuHeight, m_WindowRect.Width() - 1, -1));
00178           m_ClientRect.SetTop(iMenuHeight + 1);
00179           m_ClientRect.ClipTo(m_WindowRect.SizeRect());
00180      }
00181      else
00182      {
00183           m_ClientRect = m_WindowRect.SizeRect();
00184      }
00185 }
00186 
00187 
00188 void CFrame::SetWindowRect(const CRect& WindowRect)  // virtual
00189 {
00190      m_TitleBarRect = CRect(2, 2, WindowRect.Width() - 5, m_iTitleBarHeight);
00191      m_pFrameCloseButton->SetWindowRect(CRect(WindowRect.Width() - 20, (-m_iTitleBarHeight / 2) - 7, WindowRect.Width() - 8, (-m_iTitleBarHeight / 2) + 5));
00192      m_ClientRect = CRect(2, m_iTitleBarHeight + 2, WindowRect.Width() - 1, WindowRect.Height() - 1);
00193      // SetWindowRect() must be called last since it calls Draw(), and needs the titlebar rect and such to be set first
00194      CWindow::SetWindowRect(WindowRect);
00195 }
00196 
00197 
00198 void CFrame::SetWindowText(const std::wstring& sWindowText)  // virtual
00199 {
00200      std::auto_ptr<CRenderedString> pRenderedString(new CRenderedString(m_pFontEngine, sWindowText, CRenderedString::VALIGN_CENTER));
00201      m_pRenderedString = pRenderedString;
00202      CWindow::SetWindowText(sWindowText);
00203 }
00204 
00205 
00206 bool CFrame::OnMouseButtonDown(CPoint Point, unsigned int Button)  // virtual
00207 {
00208      bool bResult = CWindow::OnMouseButtonDown(Point, Button);
00209 
00210      if (!bResult && m_bVisible && (m_WindowRect.SizeRect().HitTest(ViewToWindow(Point)) == CRect::RELPOS_INSIDE))
00211      {
00212           if (m_TitleBarRect.HitTest(ViewToWindow(Point)) == CRect::RELPOS_INSIDE)
00213           {
00214                m_bDragMode = true;
00215                m_DragPointerStart = Point;
00216                m_FrameGhostRect = m_WindowRect;
00217                CMessageServer::Instance().QueueMessage(new CMessage(CMessage::APP_PAINT, 0, this));
00218           }
00219           SetNewParent(m_pParentWindow);     // This moves the window to the top
00220           bResult = true;
00221      }
00222 
00223      return bResult;
00224 }
00225 
00226 
00227 bool CFrame::HandleMessage(CMessage* pMessage)  // virtual
00228 {
00229      bool bHandled = false;
00230 
00231      if (pMessage)
00232      {
00233           switch(pMessage->MessageType())
00234           {
00235           case CMessage::MOUSE_MOVE:  // intentional fall through
00236           case CMessage::MOUSE_BUTTONUP:
00237           {
00238                CMouseMessage* pMouseMessage = dynamic_cast<CMouseMessage*>(pMessage);
00239                if (pMouseMessage && m_bDragMode)
00240                {
00241                     CRect MovedRect = m_WindowRect + (pMouseMessage->Point - m_DragPointerStart);
00242                     CRect Bounds = m_pParentWindow->GetClientRect().SizeRect();
00243                     if (MovedRect.Right() > Bounds.Right())
00244                     {
00245                          MovedRect.Move(Bounds.Right() - MovedRect.Right(), 0);
00246                     }
00247                     if (MovedRect.Left() < Bounds.Left())
00248                     {
00249                          MovedRect.Move(Bounds.Left() - MovedRect.Left(), 0);
00250                     }
00251                     if (MovedRect.Bottom() > Bounds.Bottom())
00252                     {
00253                          MovedRect.Move(0, Bounds.Bottom() - MovedRect.Bottom());
00254                     }
00255                     if (MovedRect.Top() < Bounds.Top())
00256                     {
00257                          MovedRect.Move(0, Bounds.Top() - MovedRect.Top());
00258                     }
00259                     if (pMessage->MessageType() == CMessage::MOUSE_BUTTONUP)
00260                     {
00261                          m_WindowRect = MovedRect;
00262                          m_bDragMode = false;
00263                          bHandled = true;
00264                     }
00265                     else
00266                     {
00267                          m_FrameGhostRect = MovedRect;
00268                     }
00269                     CMessageServer::Instance().QueueMessage(new CMessage(CMessage::APP_PAINT, 0, this));
00270                }
00271                break;
00272           }
00273           case CMessage::CTRL_SINGLELCLICK:
00274           {
00275                if (pMessage->Destination() == this)
00276                {
00277                     if (pMessage->Source() == m_pFrameCloseButton)
00278                     {
00279                          CloseFrame();
00280                          bHandled = true;
00281                     }
00282                }
00283                break;
00284           }
00285           default :
00286                bHandled = CWindow::HandleMessage(pMessage);
00287                break;
00288           }
00289      }
00290 
00291      return bHandled;
00292 }
00293 
00294 }
00295 

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