Thread: [Gcblue-commits] gcb_wx/src/graphics tcWindow.cpp,NONE,1.1 tcwindow.cpp,1.23,NONE
Status: Alpha
Brought to you by:
ddcforge
|
From: Xavi <xr...@us...> - 2004-04-04 22:02:05
|
Update of /cvsroot/gcblue/gcb_wx/src/graphics In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24645 Added Files: tcWindow.cpp Removed Files: tcwindow.cpp Log Message: + changed lowercase tcwindow.cpp to tcWindow.cpp, according to the includes from other files and the name of the class --- NEW FILE: tcWindow.cpp --- /* ** tcWindow.cpp: implementation of the tcWindow class. ** ** Copyright (C) 2003 Dewitt "Cole" Colclough (de...@tw...) ** All rights reserved. ** This file is part of the Global Conflict Blue (GCB) program. ** GCB is free software; you can redistribute it and/or modify ** it under the terms of version 2 of the GNU General Public License as ** published by the Free Software Foundation. ** GCB is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** You should have received a copy of the GNU General Public License ** along with GCB; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "stdwx.h" // precompiled header file #ifndef WX_PRECOMP #include "wx/wx.h" #include "wx/msw/private.h" // for MS Windows specific definitions #endif #include "tcWindow.h" #include "gdiplus.h" #include "tcGraphicsEngine.h" #include "aerror.h" #include <stdio.h> #include <iostream> #include "tcString.h" #include "tcSound.h" using namespace Gdiplus; BEGIN_EVENT_TABLE(tcWindow, wxWindow) //EVT_PAINT(tcWindow::OnPaint) //EVT_NC_PAINT(tcWindow::OnPaint) //EVT_ERASE_BACKGROUND(tcWindow::OnEraseBackground) EVT_MOVE(tcWindow::OnMove) EVT_LEFT_DOWN(tcWindow::OnLButtonDown) EVT_LEFT_UP(tcWindow::OnLButtonUp) EVT_RIGHT_DOWN(tcWindow::OnRButtonDown) EVT_MOTION(tcWindow::OnMouseMove) EVT_MOUSEWHEEL(tcWindow::OnMouseWheel) EVT_KEY_DOWN(tcWindow::OnKeyDown) ///< any key has been pressed EVT_CHAR(tcWindow::OnChar) EVT_ENTER_WINDOW(tcWindow::OnEnterWindow) EVT_LEAVE_WINDOW(tcWindow::OnLeaveWindow) EVT_SHOW(tcWindow::OnShow) EVT_SIZE(tcWindow::OnSize) EVT_SET_FOCUS(tcWindow::OnSetFocus) EVT_KILL_FOCUS(tcWindow::OnKillFocus) END_EVENT_TABLE() /** * This override along with use of Freeze() Thaw() prevents * the flicker that happens when the window background is erased * by wxWindows. */ long tcWindow::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) { switch (nMsg) { case WM_ERASEBKGND: return 0; break; default: return wxWindow::MSWWindowProc(nMsg, wParam, lParam); break; } } void tcWindow::OnChar(wxKeyEvent& event) { event.Skip(); } void tcWindow::OnEnterWindow(wxMouseEvent& event) { SetFocus(); } /** * Do nothing for EraseBackground event. */ void tcWindow::OnEraseBackground(wxEraseEvent& event) { SetBackgroundColour(*wxBLACK); fprintf(stdout, "Erase [%s]\n",GetName()); } /** * Do nothing for OnPaint event. */ void tcWindow::OnPaint(wxPaintEvent& event) { wxPaintDC dc(this); fprintf(stdout, "Paint [%s]\n",GetName()); } /** * Do nothing for show event. */ void tcWindow::OnShow(wxShowEvent& event) { return; } void tcWindow::OnKeyDown(wxKeyEvent& event) { event.Skip(); } void tcWindow::OnLButtonDown(wxMouseEvent& event) { SkipMouseEvent(event); } void tcWindow::OnLButtonUp(wxMouseEvent& event) { SkipMouseEvent(event); } void tcWindow::OnLeaveWindow(wxMouseEvent& event) { event.Skip(); } void tcWindow::OnMouseMove(wxMouseEvent& event) { event.Skip(); } void tcWindow::OnMouseWheel(wxMouseEvent& event) { event.Skip(); } void tcWindow::OnMove(wxMoveEvent& event) { // event.Skip(); } void tcWindow::OnRButtonDown(wxMouseEvent& event) { SkipMouseEvent(event); } void tcWindow::OnSetFocus(wxFocusEvent& event) { } void tcWindow::OnKillFocus(wxFocusEvent& event) { } void tcWindow::OnSize(wxSizeEvent& event) { wxSize size = event.GetSize(); wxPoint pos = wxWindow::GetPosition(); mnWidth = size.GetWidth(); mnHeight = size.GetHeight(); mrectWindow.left = pos.x; mrectWindow.right = pos.x + size.GetWidth(); mrectWindow.top = pos.y; mrectWindow.bottom = pos.y + size.GetHeight(); if (mbCloned) return; // do not modify shared mp2DSurface for cloned/shared windows if (resizeable2DSurface) { mp2DSurface->SetDisplayRegion(0,0,(float)mnWidth,(float)mnHeight); if (mp2DSurface->Init(mnWidth, mnHeight) != true) { wxMessageBox("Window resize failed","ERROR",wxICON_ERROR); return; } } mp2DSurface->SetWindow(mrectWindow.left, yMirror - mrectWindow.bottom, mrectWindow.right, yMirror - mrectWindow.top); mp2DSurface->mbModified = true; } /** * Adds child window to children vector. This * allows drawing of children windows through * DrawChildren() method. */ void tcWindow::AddChild(tcWindow* child) { wxASSERT(child); if (child == NULL) return; children.push_back(child); } bool tcWindow::GetDrawDC(HDC& hdc) { return mp2DSurface->GetDrawDC(hdc); } /** * @return pointer to WCHAR array (string) with IMAGE_PATH prepended, * extremely long file names can cause overrun. */ WCHAR* tcWindow::PrependImagePath(const char *azFileName) { char zBuff[96]; strcpy(zBuff,IMAGE_PATH); strcat(zBuff,azFileName); MultiByteToWideChar(CP_ACP, 0, zBuff, -1, mzwchar, 255); return mzwchar; } bool tcWindow::ReleaseDrawDC(HDC hdc) { return mp2DSurface->ReleaseDrawDC(hdc); } bool tcWindow::GetGraphics(Graphics*& rpGraphics) { if (GetDrawDC(mhdc) == false) {return false;} rpGraphics = new Graphics(mhdc); if (rpGraphics == NULL) {return false;} rpGraphics->SetCompositingMode(CompositingModeSourceOver); // SourceCopy doesn't do blending rpGraphics->SetSmoothingMode(SmoothingModeAntiAlias); rpGraphics->SetPixelOffsetMode(PixelOffsetModeHighQuality); rpGraphics->SetTextRenderingHint(TextRenderingHintAntiAlias); //rpGraphics->SetTextRenderingHint(TextRenderingHintAntiAliasGridFit); return true; } bool tcWindow::GetLowQualityGraphics(Graphics*& rpGraphics) { if (GetDrawDC(mhdc) == false) {return false;} rpGraphics = new Graphics(mhdc); if (rpGraphics == NULL) {return false;} rpGraphics->SetCompositingMode(CompositingModeSourceOver); // SourceCopy doesn't do blending rpGraphics->SetSmoothingMode(SmoothingModeHighSpeed); rpGraphics->SetPixelOffsetMode(PixelOffsetModeHighSpeed ); rpGraphics->SetTextRenderingHint(TextRenderingHintSingleBitPerPixelGridFit); return true; } bool tcWindow::ReleaseGraphics(Graphics* apGraphics) { if (apGraphics != NULL) {delete apGraphics;} return ReleaseDrawDC(mhdc); } /** * wxWindows (or MS Windows behind it) erases window region * when the window is moved or Show() is used. This causes * a flickering effect. Enable() is used to activate/deactivate * GUI inputs for the window. */ void tcWindow::SetActive(bool abActive) { if (abActive) { if (!wxWindow::IsShown()) { wxWindow::Show(TRUE); } wxWindow::Enable(true); } else { wxWindow::Enable(false); } mbActive=abActive; mp2DSurface->SetActive(abActive); size_t nChildren = children.size(); for(size_t n=0;n<nChildren;n++) { children[n]->SetActive(abActive); } } void tcWindow::SetRenderTexture(bool abState) { mp2DSurface->SetRenderTexture(abState); } /** * Used to reduce the number OpenGL 2D graphics transfers via * glDrawPixels to speed frame rate. Set to 1 to only transfer * every 3rd frame for window. Set to 2 for every 5th frame. * @see tc2DGraphicsSurface::SetSkipCount */ void tcWindow::SetSkipCount(unsigned skipCount) { mp2DSurface->SetSkipCount(skipCount); } /** * Adjusts wxMouseEvent position to parent's frame. * Calls Skip() on event. */ void tcWindow::SkipMouseEvent(wxMouseEvent& event) { wxPoint pos = wxWindow::GetPosition(); event.m_x += pos.x; event.m_y += pos.y; event.Skip(); } /** * Use this for child windows, or windows that are not * displayed at the same time as the parent window to * save memory. This must be called after the parent's surface * has been created. */ void tcWindow::ShareSurfaceWith(const tcWindow* apWindow) { wxASSERT(apWindow); wxASSERT(apWindow->mp2DSurface); mp2DSurface = apWindow->mp2DSurface; mbCloned = true; mbActive = apWindow->mbActive; } /** * Called once to register and create tc2DGraphics surface. Will * call tc2DGraphicsSurface::Init method to create bitmap for surface. * If the graphics surface has already been created this method will * log a warning and return. */ int tcWindow::CreateSurfaces(tcGraphicsEngine* apGraphicsEngine) { wxASSERT(!mbCloned); // error, parent will create surface // check if surface has already been created if (mp2DSurface) { fprintf(stderr,"WARNING: CreateSurfaces called more than once.\n"); return true; } if (apGraphicsEngine->Create2DSurface(mp2DSurface) == false) {return false;} if (yMirror) { mp2DSurface->SetWindow(mrectWindow.left, yMirror - mrectWindow.bottom, mrectWindow.right, yMirror - mrectWindow.top); } else { mp2DSurface->SetWindow(mrectWindow.left, mrectWindow.top, mrectWindow.right, mrectWindow.bottom); } mp2DSurface->SetDisplayRegion(0,0,(float)mnWidth,(float)mnHeight); if (mp2DSurface->Init(mnWidth, mnHeight) != true) {return false;} mp2DSurface->GetActive(mbActive); return true; } int tcWindow::DeleteSurfaces(tcGraphicsEngine* apGraphicsEngine) { wxASSERT(!mbCloned); // error, parent window will delete surface if (apGraphicsEngine->Delete2DSurface(mp2DSurface) == false) {return false;} mp2DSurface = NULL; mbActive = false; return true; } int tcWindow::DrawTest() { if (mp2DSurface != NULL) { mp2DSurface->DrawTestGdiPlus(); return 1; } else { return 0; } } /** * @return 1 if Draw was performed, 0 otherwise. */ int tcWindow::Draw() { return 1; } void tcWindow::Draw(Gdiplus::Graphics *graphics) { } /** * Call Draw(Gdiplus::Graphics*) method for all children */ void tcWindow::DrawChildren(Gdiplus::Graphics *graphics) { wxASSERT(graphics); size_t nChildren = children.size(); for(size_t n=0;n<nChildren;n++) { wxASSERT(children[n]); graphics->TranslateTransform(children[n]->mrectWindow.left, children[n]->mrectWindow.top); children[n]->Draw(graphics); graphics->TranslateTransform(-children[n]->mrectWindow.left, -children[n]->mrectWindow.top); } } void tcWindow::DrawText(Graphics* apGraphics, Font* apFont, Brush* apBrush, const char* azstr, float afX, float afY) { MultiByteToWideChar(CP_ACP, 0, azstr, -1, mzwchar, 255); apGraphics->DrawString(mzwchar, -1, apFont, PointF(afX,afY), apBrush); } void tcWindow::DrawText(Graphics* apGraphics, Font* apFont, Brush* apBrush, const char* azstr, float afX, float afY, RectF& r) { PointF p(afX,afY); MultiByteToWideChar(CP_ACP, 0, azstr, -1, mzwchar, 255); apGraphics->DrawString(mzwchar, -1, apFont, p, apBrush); apGraphics->MeasureString(mzwchar,-1,apFont,p, &r); } /** * Draws horizontally centered text */ void tcWindow::DrawTextCentered(Graphics* apGraphics, Font* apFont, Brush* apBrush, const char* azstr, float afX, float afY) { MultiByteToWideChar(CP_ACP, 0, azstr, -1, mzwchar, 255); apGraphics->DrawString(mzwchar, -1, apFont, PointF(afX,afY), &stringformatcentered, apBrush); } /** * Draws horizontally and vertically centered text */ void tcWindow::DrawTextCenteredHV(Gdiplus::Graphics* apGraphics, Gdiplus::Font* apFont, Gdiplus::Brush* apBrush, const char* azstr, float x, float y) { RectF r; MultiByteToWideChar(CP_ACP, 0, azstr, -1, mzwchar, 255); apGraphics->MeasureString(mzwchar, -1, apFont, PointF(0,0), &r); float dx = r.X + 0.5*r.Width; float dy = r.Y + 0.5*r.Height; apGraphics->DrawString(mzwchar, -1, apFont, PointF(x-dx,y-dy), apBrush); } void tcWindow::DrawTextInRect(Graphics* apGraphics, Font* apFont, Brush* apBrush, const char* azstr, RectF& rect) { MultiByteToWideChar(CP_ACP, 0, azstr, -1, mzwchar, 255); apGraphics->DrawString(mzwchar, -1, apFont, rect, &stringformatleftalign, apBrush); } void tcWindow::DrawTextInRectWrap(Graphics* apGraphics, Font* apFont, Brush* apBrush, const char* azstr, RectF& rect) { MultiByteToWideChar(CP_ACP, 0, azstr, -1, mzwchar, 255); apGraphics->DrawString(mzwchar, -1, apFont, rect, &stringformatwrap, apBrush); } void tcWindow::MeasureText(Graphics* apGraphics, Font* apFont, const char* azstr, SizeF& size) { RectF r; // this conversion ends up being done twice if DrawText is called after this MultiByteToWideChar(CP_ACP, 0, azstr, -1, mzwchar, 255); apGraphics->MeasureString(mzwchar,-1,apFont,PointF(0,0),&r); size.Width = r.Width; size.Height = r.Height; } /* Erase the surface with alpha = 0 */ void tcWindow::Erase() { mp2DSurface->Erase(); } /* Erase with alpha = 0xFF */ void tcWindow::EraseOpaque() { mp2DSurface->EraseOpaque(); } void tcWindow::Freeze() { if (!mbFrozen) wxWindow::Freeze(); mbFrozen = true; } wxBitmap* tcWindow::GetBitmap() { return mp2DSurface->GetBitmap(); } bool tcWindow::IsSurfaceModified() { return mp2DSurface->mbModified; } void tcWindow::LoadBackgroundImage(char *azFileName) { char zBuff[64]; if (mpiBackground != NULL) {delete mpiBackground;} // de-allocate existing image strcpy(zBuff,IMAGE_PATH); strcat(zBuff,azFileName); MultiByteToWideChar(CP_ACP, 0, zBuff, -1, mzwchar, 255); mpiBackground = new Image(mzwchar,false); if (mpiBackground==NULL) {WTL("tcWindow::LoadBackgroundImage - failed to load background image");} } /** * Loads image (prepends image path automatically) */ Gdiplus::Image* tcWindow::LoadImage(const char *fileName) { Gdiplus::Image* image; std::string path = IMAGE_PATH; path += fileName; MultiByteToWideChar(CP_ACP, 0, path.c_str(), -1, mzwchar, 255); image = new Image(mzwchar,false); if (image==NULL) { std::cerr << "tcWindow::LoadImage - " << path << " failed." << std::endl; } return image; } void tcWindow::SetBackground(UINT32 anColor) { mp2DSurface->SetBackground(anColor); } /** * @return alpha blending state for window. */ bool tcWindow::GetBlend() { return mp2DSurface->GetBlend(); } /** * Used to enable or disable (default state) alpha blending * for window. */ void tcWindow::SetBlend(bool blendingOn) { mp2DSurface->SetBlend(blendingOn); } void tcWindow::SetOpaque() { mp2DSurface->SetOpaque(); } void tcWindow::SetPixel(int x, int y, unsigned int value) { if (mp2DSurface != NULL) { mp2DSurface->SetPixel(x,y,value); } } /* draw background image if one is loaded, otherwise fill with black */ void tcWindow::DrawBackground(Graphics *apGraphics) { if (mpiBackground == NULL) { Color startcolor; mpBrushDefault->GetColor(&startcolor); mpBrushDefault->SetColor(Color(255,0,0,0)); apGraphics->FillRectangle(mpBrushDefault,0,0,mnWidth,mnHeight); mpBrushDefault->SetColor(startcolor); } else { apGraphics->DrawImage(mpiBackground,0,0); } } /* Draw a border */ void tcWindow::DrawBorder() { mp2DSurface->DrawBorder(); } /** * Sets region of window to display. This is intended * to provide a zoomed view of a window e.g. the view * area of the terrain map is a small region of the overall * map that is zoomed to fit the map window. * @param r RectF structure defining the display region bounds. */ void tcWindow::SetDisplayRegion(RectF r) { mp2DSurface->SetDisplayRegion(r.X,r.Y,r.GetRight(),r.GetBottom()); mrectDisplay = r; } void tcWindow::MoveToTop() { if (!tcGraphicsEngine::Get()->MoveSurfaceToTop(mp2DSurface)) { std::cerr << "Error - tcWindow::MoveToTop() - surface not found" << std::endl; } if (mbCloned) { std::cerr << "Warning - tcWindow::MoveToTop() - called on shared surface" << std::endl; } } void tcWindow::MoveWindow(int ax, int ay) { mrectWindow.left = ax; mrectWindow.top = ay; mrectWindow.right = ax + mnWidth; mrectWindow.bottom = ay + mnHeight; if (yMirror) mp2DSurface->MoveWindow(ax,yMirror-mrectWindow.bottom); else mp2DSurface->MoveWindow(ax,ay); wxWindow::Move(wxPoint(ax,ay)); } void tcWindow::Thaw() { if (mbFrozen) { wxWindow::Thaw(); mbFrozen = false; } } ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// tcWindow::tcWindow(wxWindow *parent, const wxPoint& pos, const wxSize& size, const wxString& name, tcWindow *sharedSurfaceHost) : wxWindow(parent, -1, pos, size, wxTRANSPARENT_WINDOW | wxNO_FULL_REPAINT_ON_RESIZE, name), //| wxNO_FULL_REPAINT_ON_RESIZE |wxCLIP_CHILDREN mnHeight(size.GetHeight()), mnWidth(size.GetWidth()) { wxWindow::SetBackgroundColour(*wxBLACK); wxWindow::Show(FALSE); mbActive = false; mp2DSurface = NULL; mrectWindow.left = pos.x; mrectWindow.right = pos.x + size.GetWidth(); mrectWindow.top = pos.y; mrectWindow.bottom = pos.y + size.GetHeight(); mpiBackground = NULL; mbFrozen = false; if (sharedSurfaceHost) { mbCloned = true; resizeable2DSurface = false; yMirror = 0; tcWindow::ShareSurfaceWith(sharedSurfaceHost); if (parent == static_cast<wxWindow*>(sharedSurfaceHost)) // if parent matches sharedSurfaceHost { sharedSurfaceHost->AddChild(this); // adds this to parent's list of children to draw } } else { mbCloned = false; resizeable2DSurface = true; wxSize parentSize = parent->GetSize(); yMirror = parentSize.GetHeight(); if (!CreateSurfaces(tcGraphicsEngine::Get())) { throw "Failed to create 2D surface"; } } mhFontDefault = CreateFont(20,0,0,0,FW_BOLD,FALSE,FALSE,FALSE, ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, DEFAULT_PITCH|FF_MODERN,"Arial"); if (mhFontDefault == NULL) { WTL("mhFontDefault creation failed\n"); ShowAndAbort("mhFontDefault creation failed\n"); } FontFamily ff(L"Arial"); mpFontDefault = new Font(&ff,16,FontStyleBold,UnitPixel); if (mpFontDefault == NULL) {WTL("tcWindow - mpFontDefault creation failed\n");} mpBrushDefault = new SolidBrush(Color(0xFEFFFFFF)); // color is ARGB if (mpBrushDefault == NULL) {WTL("tcWindow - mpBrushDefault creation failed\n");} stringformatleftalign.SetFormatFlags(StringFormatFlagsNoWrap); stringformatleftalign.SetAlignment(StringAlignmentNear); stringformatleftalign.SetTrimming(StringTrimmingEllipsisCharacter); //stringformatleftalign.SetTrimming(StringTrimmingNone); //stringformatwrap.SetFormatFlags(StringFormatFlagsWrap); stringformatwrap.SetAlignment(StringAlignmentNear); stringformatwrap.SetTrimming(StringTrimmingEllipsisCharacter); stringformatcentered.SetAlignment(StringAlignmentCenter); } tcWindow::~tcWindow() { if (mpFontDefault != NULL) {delete mpFontDefault;} if (mpBrushDefault != NULL) {delete mpBrushDefault;} if (mpiBackground != NULL) {delete mpiBackground;} // delete surface if not a shared surface if (!mbCloned) { if (!tcGraphicsEngine::Get()->Delete2DSurface(mp2DSurface)) { std::cerr << "Warning - tcWindow::~tcWindow() 2D surface not found" << std::endl; } } } --- tcwindow.cpp DELETED --- |