void ScheduleViewEx::OnDraw(CDC* pDC) { Periods& periods = static_cast<CScheduleApp*>(AfxGetApp())->m_periods; Period& period = periods.GetCurrentPeriod(); CTime startDay = period.m_dateRange.GetStartDate(); startDay = startDay + CTimeSpan(xDelta*GetXOffset(),0,0,0); CTime stopDay = startDay + CTimeSpan(xDelta,0,0,0); Truncate(startDay,period.m_dateRange.GetStartDate(), period.m_dateRange.GetEndDate()); Truncate(stopDay,period.m_dateRange.GetStartDate(), period.m_dateRange.GetEndDate()); int startNurse = yDelta * GetYOffset(); int stopNurse = startNurse + yDelta; CString outputText = ViewOutput(startDay,stopDay, startNurse,stopNurse); CFont tmpcourierFont; if (pDC->m_bPrinting) tmpcourierFont.CreatePointFont(printFontSize,_T("Lucida Console")); else tmpcourierFont.CreatePointFont(viewFontSize,_T("Lucida Console")); LOGFONT logFont; tmpcourierFont.GetLogFont(&logFont); logFont.lfUnderline = 1; CFont courierFont; courierFont.CreateFontIndirect(&logFont); CFont * oldFont; oldFont = pDC->SelectObject(&courierFont); pDC->DrawText(outputText,CRect(250,-250,250,-250),DT_NOCLIP); if (!pDC->m_bPrinting) { CRect rcOut(0,0,0,0); VERIFY(pDC->DrawText(outputText,&rcOut,DT_NOCLIP | DT_CALCRECT)); CSize newSize(rcOut.right*1.1,(rcOut.bottom*-1)*1.1); if (newSize != m_oldSize) { SetScrollSizes(MM_HIENGLISH,newSize); m_oldSize = newSize; } } CFont * tmpFont = pDC->SelectObject(oldFont); ASSERT(tmpFont = &courierFont); }
bool IW::Scale(const IW::Image &imageIn, IW::Image &imageOut, CSize size, IW::IStatus *pStatus) { const CRect rcBounding = imageIn.GetBoundingRect(); int cxBounding = rcBounding.Width(); int cyBounding = rcBounding.Height(); // zoom scale factors const double dScaleX = (double) size.cx / (double) cxBounding; const double dScaleY = (double) size.cy / (double) cyBounding; for(IW::Image::PageList::const_iterator pageIn = imageIn.Pages.begin(); pageIn != imageIn.Pages.end(); ++pageIn) { CRect rcIn = pageIn->GetPageRect(); CRect rcOut( MulDiv(rcIn.left, size.cx, cxBounding), MulDiv(rcIn.top, size.cy, cyBounding), MulDiv(rcIn.right, size.cx, cxBounding), MulDiv(rcIn.bottom, size.cy, cyBounding)); IW::PixelFormat pf(pageIn->GetPixelFormat().HasAlpha() ? IW::PixelFormat::PF32Alpha : IW::PixelFormat::PF24); IW::Page &pageOut = imageOut.CreatePage(rcOut, pf); IW::IImageSurfaceLockPtr pLockOut = pageOut.GetSurfaceLock(); if (CanUseMMX()) { RenderImage<IW::IImageSurfaceLock, CBlitterMMX> render(*pLockOut, CBlitterMMX()); render.DrawImage(*pageIn, rcOut, rcIn); } else { RenderImage<IW::IImageSurfaceLock, CBlitter> render(*pLockOut, CBlitter()); render.DrawImage(*pageIn, rcOut, rcIn); } pageOut.CopyExtraInfo(*pageIn); } imageOut.Normalize(); IW::IterateImageMetaData(imageIn, imageOut, pStatus); return true; };
void C4GraphicsSystem::RecalculateViewports() { // Fullscreen only if (!Application.isFullScreen) return; // Sort viewports SortViewportsByPlayerControl(); // Viewport area int32_t iBorderTop = 0, iBorderBottom = 0; if (Config.Graphics.UpperBoard) iBorderTop = C4UpperBoardHeight; iBorderBottom = MessageBoard.Output.Hgt; ViewportArea.Set(Application.DDraw->lpBack,0,iBorderTop, Config.Graphics.ResX, Config.Graphics.ResY-iBorderTop-iBorderBottom); // Redraw flag InvalidateBg(); #ifdef _WIN32 // reset mouse clipping ClipCursor(NULL); #else // StdWindow handles this. #endif // reset GUI dlg pos if (Game.pGUI) Game.pGUI->SetPreferredDlgRect(C4Rect(ViewportArea.X, ViewportArea.Y, ViewportArea.Wdt, ViewportArea.Hgt)); // fullscreen background: First, cover all of screen BackgroundAreas.Clear(); BackgroundAreas.AddRect(C4Rect(ViewportArea.X, ViewportArea.Y, ViewportArea.Wdt, ViewportArea.Hgt)); // Viewports C4Viewport *cvp; int32_t iViews = 0; for (cvp=FirstViewport; cvp; cvp=cvp->Next) iViews++; if (!iViews) return; int32_t iViewsH = (int32_t) sqrt(float(iViews)); int32_t iViewsX = iViews / iViewsH; int32_t iViewsL = iViews % iViewsH; int32_t cViewH,cViewX,ciViewsX; int32_t cViewWdt,cViewHgt,cOffWdt,cOffHgt,cOffX,cOffY; cvp=FirstViewport; for (cViewH=0; cViewH<iViewsH; cViewH++) { ciViewsX = iViewsX; if (cViewH<iViewsL) ciViewsX++; for (cViewX=0; cViewX<ciViewsX; cViewX++) { cViewWdt = ViewportArea.Wdt/ciViewsX; cViewHgt = ViewportArea.Hgt/iViewsH; cOffX = ViewportArea.X; cOffY = ViewportArea.Y; cOffWdt=cOffHgt=0; int32_t ViewportScrollBorder = Application.isFullScreen ? C4ViewportScrollBorder : 0; if (ciViewsX*Min<int32_t>(cViewWdt, GBackWdt+2*ViewportScrollBorder)<ViewportArea.Wdt) cOffX=(ViewportArea.Wdt-ciViewsX*Min<int32_t>(cViewWdt, GBackWdt+2*ViewportScrollBorder))/2; if (iViewsH*Min<int32_t>(cViewHgt, GBackHgt+2*ViewportScrollBorder)<ViewportArea.Hgt) cOffY=(ViewportArea.Hgt-iViewsH*Min<int32_t>(cViewHgt, GBackHgt+2*ViewportScrollBorder))/2 + ViewportArea.Y; if (Config.Graphics.SplitscreenDividers) { if (cViewX<ciViewsX-1) cOffWdt=4; if (cViewH<iViewsH-1) cOffHgt=4; } int32_t coViewWdt=cViewWdt-cOffWdt; if (coViewWdt>GBackWdt+2*ViewportScrollBorder) { coViewWdt=GBackWdt+2*ViewportScrollBorder; } int32_t coViewHgt=cViewHgt-cOffHgt; if (coViewHgt>GBackHgt+2*ViewportScrollBorder) { coViewHgt=GBackHgt+2*ViewportScrollBorder; } C4Rect rcOut(cOffX+cViewX*cViewWdt, cOffY+cViewH*cViewHgt, coViewWdt, coViewHgt); cvp->SetOutputSize(rcOut.x,rcOut.y,rcOut.x,rcOut.y,rcOut.Wdt,rcOut.Hgt); cvp=cvp->Next; // clip down area avaiable for background drawing BackgroundAreas.ClipByRect(rcOut); } } }
bool Screen::MouseInput(int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam, Dialog *pForDlg, class C4Viewport *pForVP) { // help mode and button pressed: Abort help and discard button if (Game.MouseControl.IsHelp()) { switch (iButton) { case C4MC_Button_None: // just movement break; case C4MC_Button_LeftDown: case C4MC_Button_RightDown: // special for left/right down: Just ignore them, but don't stop help yet // help should be stopped on button-up, so these won't be processed iButton = C4MC_Button_None; break; default: // buttons stop help Game.MouseControl.AbortHelp(); iButton = C4MC_Button_None; break; } } // forward to mouse Mouse.Input(iButton, iX, iY, dwKeyParam); // dragging if (Mouse.pDragElement) { int32_t iX2=iX, iY2=iY; Mouse.pDragElement->ScreenPos2ClientPos(iX2, iY2); if (!Mouse.IsLDown()) { // stop dragging Mouse.pDragElement->StopDragging(Mouse, iX2, iY2, dwKeyParam); Mouse.pDragElement = NULL; } else { // continue dragging Mouse.pDragElement->DoDragging(Mouse, iX2, iY2, dwKeyParam); } } // backup previous MouseOver-element Mouse.pPrevMouseOverElement = Mouse.pMouseOverElement; Mouse.pMouseOverElement = NULL; bool fProcessed = false; // active context menu? if (!pForVP && pContext && pContext->CtxMouseInput(Mouse, iButton, iX, iY, dwKeyParam)) { // processed by context menu: OK! } // otherwise: active dlg and inside screen? (or direct forward to specific dlg/viewport dlg) else if (rcBounds.Contains(iX, iY) || pForDlg || pForVP) { // context menu open but mouse down command issued? close context then if (pContext && (iButton == C4MC_Button_LeftDown || iButton == C4MC_Button_RightDown)) AbortContext(true); // get client pos if (!pForDlg && !pForVP) { C4Rect &rcClientArea = GetClientRect(); iX -= rcClientArea.x; iY -= rcClientArea.y; } // exclusive mode: process active dialog only if (IsExclusive() && !pForDlg && !pForVP) { if (pActiveDlg && pActiveDlg->IsVisible() && !pActiveDlg->IsFading()) { // bounds check to dlg: only if not dragging C4Rect &rcDlgBounds = pActiveDlg->GetBounds(); if (Mouse.IsLDown() || rcDlgBounds.Contains(iX, iY)) // forward to active dialog pActiveDlg->MouseInput(Mouse, iButton, iX - rcDlgBounds.x, iY - rcDlgBounds.y, dwKeyParam); else Mouse.pMouseOverElement = NULL; } else // outside dialog: own handling (for screen context menu) Window::MouseInput(Mouse, iButton, iX, iY, dwKeyParam); } else { // non-exclusive mode: process all dialogs; make them active on left-click Dialog *pDlg; for (Element *pEl = pLast; pEl; pEl = pEl->GetPrev()) if (pDlg = pEl->GetDlg()) if (pDlg->IsShown()) { // if specified: process specified dlg only if (pForDlg && pDlg != pForDlg) continue; // if specified: process specified viewport only bool fIsExternalDrawDialog = pDlg->IsExternalDrawDialog(); C4Viewport *pVP = fIsExternalDrawDialog ? pDlg->GetViewport() : NULL; if (pForVP && pForVP != pVP) continue; // calc offset C4Rect &rcDlgBounds = pDlg->GetBounds(); int32_t iOffX=0, iOffY=0; // special handling for viewport dialogs if (fIsExternalDrawDialog) { // ignore external drawing dialogs without a viepwort assigned if (!pVP) continue; // always clip to viewport bounds C4Rect rcOut(pVP->GetOutputRect()); if (!rcOut.Contains(iX + rcBounds.x, iY + rcBounds.y)) continue; // viewport dialogs: Offset determined by viewport position iOffX = rcOut.x; iOffY = rcOut.y; } // hit test; or special: dragging possible outside active dialog if (rcDlgBounds.Contains(iX-iOffX, iY-iOffY) || (pDlg == pActiveDlg && Mouse.pDragElement)) { // Okay; do input pDlg->MouseInput(Mouse, iButton, iX - rcDlgBounds.x - iOffX, iY - rcDlgBounds.y - iOffY, dwKeyParam); // dlgs may destroy GUI if (!IsGUIValid()) return false; // CAUTION: pDlg may be invalid now! // set processed-flag manually fProcessed = true; // inactive dialogs get activated by clicks if (Mouse.IsLDown() && pDlg != pActiveDlg) // but not viewport dialogs! if (!pDlg->IsExternalDrawDialog()) ActivateDialog(pDlg); // one dlg only; break loop here break; } } } // check valid GUI; might be destroyed by mouse input if (!IsGUIValid()) return false; } // check if MouseOver has changed if (Mouse.pPrevMouseOverElement != Mouse.pMouseOverElement) { // send events if (Mouse.pPrevMouseOverElement) Mouse.pPrevMouseOverElement->MouseLeave(Mouse); if (Mouse.pMouseOverElement) Mouse.pMouseOverElement->MouseEnter(Mouse); } // return whether anything processed it return fProcessed || Mouse.pDragElement || (Mouse.pMouseOverElement && Mouse.pMouseOverElement!=this) || pContext; }