CRGBColor CPainter::ReadPoint(const CPoint& Point) { CPoint RealPoint = (m_pWindow != 0) ? Point + m_pWindow->GetClientRect().TopLeft() : Point; Uint32 PixelColor = 0; if (CRect(0, 0, m_pSurface->w, m_pSurface->h).HitTest(RealPoint) == CRect::RELPOS_INSIDE) { Uint8* PixelOffset = static_cast<Uint8*>(m_pSurface->pixels) + m_pSurface->format->BytesPerPixel * RealPoint.XPos() + m_pSurface->pitch * RealPoint.YPos(); switch (m_pSurface->format->BytesPerPixel) { case 1: // 8 bpp PixelColor = *reinterpret_cast<Uint8*>(PixelOffset); break; case 2: // 16 bpp PixelColor = *reinterpret_cast<Uint16*>(PixelOffset); break; case 3: // 24 bpp { Uint8* pPixelDest = reinterpret_cast<Uint8*>(&PixelColor); Uint8* pPixelSource = reinterpret_cast<Uint8*>(PixelOffset); *pPixelDest = *pPixelSource; *(++pPixelDest) = *(++pPixelSource); *(++pPixelDest) = *(++pPixelSource); break; } case 4: // 32 bpp PixelColor = *reinterpret_cast<Uint32*>(PixelOffset); break; default: throw(Wg_Ex_SDL("CPainter::DrawPoint : Unrecognized BytesPerPixel.")); break; } } return CRGBColor(&PixelColor, m_pSurface->format); }
CView::CView(SDL_Surface* surface, SDL_Surface* backSurface, const CRect& WindowRect) : CWindow(CRect(0, 0, surface->w, surface->h), 0), m_pMenu(0), m_pFloatingWindow(0), m_pScreenSurface(0) { if (m_pInstance) { throw(Wg_Ex_App("Cannot have more than one view at a time!")); } m_pInstance = this; CMessageServer::Instance().RegisterMessageClient(this, CMessage::APP_PAINT); CMessageServer::Instance().RegisterMessageClient(this, CMessage::APP_DESTROY_FRAME, CMessageServer::PRIORITY_FIRST); CMessageServer::Instance().RegisterMessageClient(this, CMessage::CTRL_RESIZE); CMessageServer::Instance().RegisterMessageClient(this, CMessage::MOUSE_BUTTONDOWN, CMessageServer::PRIORITY_FIRST); CMessageServer::Instance().RegisterMessageClient(this, CMessage::MOUSE_BUTTONUP, CMessageServer::PRIORITY_FIRST); // judb this works, but better rewrite this to make things clearer ! CWindow::SetWindowRect(WindowRect); // judb ClientRect is relative to WindowRect (it is the client area within a Window(Rect) ) so // its coordinates are relative to WindowRect -> // here we use a rectangle with the same dimensions as WindowRect, but (0,0) as its upper left point. // so it covers the entire WindowRect. m_ClientRect = WindowRect.SizeRect(); m_pScreenSurface = surface; m_pBackSurface = backSurface; // judb should not happen:-) if (m_pScreenSurface == NULL) throw( Wg_Ex_SDL(std::string("Surface not created? : ") + SDL_GetError())); CApplication::Instance()->GetApplicationLog().AddLogEntry("Created new CView ", APP_LOG_INFO); Draw(); }
void CPainter::LockSurface(void) { if (SDL_MUSTLOCK(m_pSurface)) { if (SDL_LockSurface(m_pSurface) < 0) { SDL_Delay(10); if (SDL_LockSurface(m_pSurface) < 0) { throw(Wg_Ex_SDL("Unable to lock surface.")); } } } }
void CView::SetWindowRect(const CRect& WindowRect) { CWindow::SetWindowRect(WindowRect); m_ClientRect = CRect(0, 0, m_WindowRect.Width(), m_WindowRect.Height()); Uint32 iFlags = SDL_SWSURFACE | SDL_ANYFORMAT ; if (m_bResizable && !m_bFullScreen) { iFlags |= SDL_RESIZABLE ; } if (m_bFullScreen) { iFlags |= SDL_FULLSCREEN ; m_bResizable = false; } m_pScreenSurface = SDL_SetVideoMode(m_WindowRect.Width(), m_WindowRect.Height(), CApplication::Instance()->GetBitsPerPixel(), iFlags); if (m_pScreenSurface == NULL) throw( Wg_Ex_SDL(std::string("Could not set video mode: ") + SDL_GetError()) ); }
bool CView::HandleMessage(CMessage* pMessage) { bool bHandled = false; if (pMessage) { switch(pMessage->MessageType()) { case CMessage::APP_PAINT : if (pMessage->Destination() == this || pMessage->Destination() == 0) { vid_plugin->lock(); SDL_Surface* pFloatingSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, m_pScreenSurface->w, m_pScreenSurface->h, CApplication::Instance()->GetBitsPerPixel(), 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000); PaintToSurface(*m_pScreenSurface, *pFloatingSurface, CPoint(0, 0)); // judb use entire application SDL surface (otherwise strange clipping effects occur // when moving frames, also clipping of listboxes.) // SDL_Rect SourceRect = CRect(m_WindowRect.SizeRect()).SDLRect(); SDL_Rect SourceRect = CRect(0, 0, m_pScreenSurface->w, m_pScreenSurface->h).SDLRect(); // SDL_Rect DestRect = CRect(m_WindowRect.SizeRect()).SDLRect(); SDL_Rect DestRect = CRect(0, 0, m_pScreenSurface->w, m_pScreenSurface->h).SDLRect(); SDL_BlitSurface(pFloatingSurface, &SourceRect, m_pScreenSurface, &DestRect); SDL_FreeSurface(pFloatingSurface); //SDL_UpdateRect(m_pScreenSurface, 0, 0, 0, 0); vid_plugin->unlock(); vid_plugin->flip(); bHandled = true; } break; case CMessage::APP_DESTROY_FRAME: if (pMessage->Destination() == this || pMessage->Destination() == 0) { CFrame* pFrame = dynamic_cast<CFrame*>(const_cast<CMessageClient*>(pMessage->Source())); if (pFrame) { pFrame->SetModal(false); pFrame->SetNewParent(0); CMessageServer::Instance().QueueMessage(new CMessage(CMessage::APP_PAINT, 0, this)); delete pFrame; } bHandled = true; } break; case CMessage::CTRL_RESIZE: { TPointMessage* pResizeMessage = dynamic_cast<TPointMessage*>(pMessage); if (pResizeMessage && pResizeMessage->Source() == CApplication::Instance()) { CWindow::SetWindowRect(CRect(m_WindowRect.TopLeft(), m_WindowRect.TopLeft() + pResizeMessage->Value())); Uint32 iFlags = SDL_SWSURFACE | SDL_ANYFORMAT; if(m_bResizable) { iFlags |= SDL_RESIZABLE; } m_ClientRect = CRect(m_ClientRect.Left(), m_ClientRect.Top(), m_WindowRect.Width(), m_WindowRect.Height()); m_ClientRect.ClipTo(m_WindowRect.SizeRect()); m_pScreenSurface = SDL_SetVideoMode(m_WindowRect.Width(), m_WindowRect.Height(), DEFAULT_BPP, iFlags); if (m_pScreenSurface == NULL) throw( Wg_Ex_SDL(std::string("Could not set video mode : ") + SDL_GetError()) ); bHandled = true; } break; } case CMessage::MOUSE_BUTTONDOWN: { CMouseMessage* pMouseMessage = dynamic_cast<CMouseMessage*>(pMessage); if (pMouseMessage && m_WindowRect.HitTest(pMouseMessage->Point) == CRect::RELPOS_INSIDE) { if (!m_pFloatingWindow || !m_pFloatingWindow->OnMouseButtonDown(pMouseMessage->Point, pMouseMessage->Button)) { if (pMouseMessage->Destination() == 0) { OnMouseButtonDown(pMouseMessage->Point, pMouseMessage->Button); } else if (dynamic_cast<const CWindow*>(pMouseMessage->Destination())) { const_cast<CWindow*>(static_cast<const CWindow*>(pMouseMessage->Destination()))-> OnMouseButtonDown(pMouseMessage->Point, pMouseMessage->Button); } } } break; } case CMessage::MOUSE_BUTTONUP: { CMouseMessage* pMouseMessage = dynamic_cast<CMouseMessage*>(pMessage); if (pMouseMessage && m_WindowRect.HitTest(pMouseMessage->Point) == CRect::RELPOS_INSIDE) { if (!m_pFloatingWindow || !m_pFloatingWindow->OnMouseButtonUp(pMouseMessage->Point, pMouseMessage->Button)) { if (pMouseMessage->Destination() == 0) { OnMouseButtonUp(pMouseMessage->Point, pMouseMessage->Button); } else if (dynamic_cast<const CWindow*>(pMouseMessage->Destination())) { const_cast<CWindow*>(static_cast<const CWindow*>(pMouseMessage->Destination()))-> OnMouseButtonUp(pMouseMessage->Point, pMouseMessage->Button); } } } break; } default : bHandled = CWindow::HandleMessage(pMessage); break; } } return bHandled; }