/*************************************************************************/ /** Copyright. **/ /** FileName: wxLCDBase.cpp **/ /** Author: Polarix **/ /** Description: LCD display panel in wxWidgets frame. **/ /*************************************************************************/ //=======================================================================// //= Include files. =// //=======================================================================// #include #include #include "wxLCDBase.h" //=======================================================================// //= Marco declare. =// //=======================================================================// #define wxLCD_ERROR_STOP_PROC_P(P, R, V) {if(NULL == P){R=V; break;}} const wxSize wxDefaultSizeInPixel(128, 64); //=======================================================================// //= Event table. =// //=======================================================================// BEGIN_EVENT_TABLE(wxLCDBase,wxWindow) EVT_PAINT (wxLCDBase::OnPaint) EVT_ERASE_BACKGROUND (wxLCDBase::OnEraseBackGround) EVT_KEY_DOWN (wxLCDBase::OnKeyDown) END_EVENT_TABLE() //=======================================================================// //= Function define. =// //=======================================================================// wxLCDBase::wxLCDBase(wxWindow *pclsParent, wxWindowID iWinID, const wxPoint& clsPosition, const wxSize& clsSizeInPixel): wxWindow(pclsParent, iWinID, clsPosition, wxDefaultSize, wxTAB_TRAVERSAL | wxNO_BORDER, wxPanelNameStr), m_clsCDC(this) { /*----------------------------------*/ /* Initialize member. */ /*----------------------------------*/ // Initialize panel size. if(wxDefaultSize == clsSizeInPixel) { m_clsSizeInPixel.Set(WX_LCD_DEFAULT_WIDTH_PIX, WX_LCD_DEFAULT_HEIGHT_PIX); } else { m_clsSizeInPixel = clsSizeInPixel; } // Initialize paint buffer and function pointer. m_ppuiDisplayBuffer = nullptr; m_pfDrawPoint = nullptr; m_iLockLevel = 0; // Process initialize. m_bIsOK = _initialize(); } wxLCDBase::~wxLCDBase() { _freeDisplayBuffer(m_ppuiDisplayBuffer); } bool wxLCDBase::_initialize(void) { /*----------------------------------*/ /* Variable Declaration */ /*----------------------------------*/ bool bReturn; /*----------------------------------*/ /* Initialize */ /*----------------------------------*/ bReturn = true; /*----------------------------------*/ /* Process */ /*----------------------------------*/ do { // Create display buffer. m_ppuiDisplayBuffer = _createNewDisplayBuffer(m_clsSizeInPixel.GetWidth(), m_clsSizeInPixel.GetHeight()); wxLCD_ERROR_STOP_PROC_P(m_ppuiDisplayBuffer, bReturn, false); // Set pixel size. SetPixelSize(WX_LCD_DEFAULT_PIX_SIZE); // Set grid visible. SetGridVisibled(WX_LCD_DEFAULT_GRID_VISIBLE); }while(0); return bReturn; } void wxLCDBase::_getBestSize(wxSize& clsBestSize) const { /*----------------------------------*/ /* Variable Declaration */ /*----------------------------------*/ bool bGridIsVisible; /*----------------------------------*/ /* Initialize */ /*----------------------------------*/ bGridIsVisible = GetGridVisibled(); /*----------------------------------*/ /* Process */ /*----------------------------------*/ // Set size object value. clsBestSize.SetWidth(m_clsSizeInPixel.GetWidth()*m_iPixelSize+(bGridIsVisible?1:0)); clsBestSize.SetHeight(m_clsSizeInPixel.GetHeight()*m_iPixelSize+(bGridIsVisible?1:0)); } void wxLCDBase::SetPixelNumber(int iHorizontalPixelNumber, int iVerticalPixelNumber) { /*----------------------------------*/ /* Variable Declaration */ /*----------------------------------*/ unsigned int** ppuiNewDisplayBuffer; int iCopiedRowNumber; int iCopiedColumnNumber; /*----------------------------------*/ /* Initialize */ /*----------------------------------*/ ppuiNewDisplayBuffer = NULL; /*----------------------------------*/ /* Process */ /*----------------------------------*/ if((iHorizontalPixelNumber > 0) && (iVerticalPixelNumber > 0)) { // Create a new display buffer ppuiNewDisplayBuffer = _createNewDisplayBuffer(iHorizontalPixelNumber, iVerticalPixelNumber); if(NULL != ppuiNewDisplayBuffer) { _enterPaintCriticalSection(); iCopiedRowNumber = m_clsSizeInPixel.GetHeight() 0)) { _enterPaintCriticalSection(); // Cleanup display and set display buffer . for(int iIdxV=0; iIdxV 0)) { _enterPaintCriticalSection(); // Cleanup display and set display buffer . for(int iIdxV=0; iIdxV*m_pfDrawPoint)(m_clsCDC, iPosX, iPosY, m_iPixelSize); } if(nullptr != m_ppuiDisplayBuffer) { *(*(m_ppuiDisplayBuffer+iPosY)+iPosX) = clsColor.GetRGBA(); } SetPixelUnitColor(iPosX, iPosY, clsColor); _releaseDC(m_clsCDC); _leavePaintCriticalSection(); } } /*************************************************************************/ /** Function Name: RefreshDisplay **/ /** Class: wxLCDBase **/ /** Accessibility: Public. **/ /** Purpose: Repaint LCD screen panel. **/ /** Params: None. **/ /** Return: None. **/ /** Notice: Call this function after the SetPixelColor called, **/ /** all pixels of the LCD panel will be repaint by the **/ /** pixels's RGBA value register array. **/ /*************************************************************************/ void wxLCDBase::RefreshDisplay(void) { /*----------------------------------*/ /* Variable Declaration */ /*----------------------------------*/ int iPaintSizeWidth, iPaintSizeHeight; bool bGridVisible; unsigned int uiColorRGBA; /*----------------------------------*/ /* Initialize */ /*----------------------------------*/ iPaintSizeWidth = m_clsSizeInPixel.GetWidth()*m_iPixelSize; iPaintSizeHeight = m_clsSizeInPixel.GetHeight()*m_iPixelSize; bGridVisible = GetGridVisibled(); // Set buffer size. if(true == bGridVisible) { iPaintSizeWidth++; iPaintSizeHeight++; } _enterPaintCriticalSection(); // Create buffer image and DC object. wxBitmap clsBufferImage(iPaintSizeWidth, iPaintSizeHeight); wxBufferedDC clsBufferedDC(&m_clsCDC, clsBufferImage); // Clear background for grid line. if(true == bGridVisible) { _setDCColor(m_clsGridColor); _prepareDC(clsBufferedDC); clsBufferedDC.DrawRectangle(wxPoint(0, 0), wxSize( m_clsSizeInPixel.GetWidth()*m_iPixelSize+1, m_clsSizeInPixel.GetHeight()*m_iPixelSize+1)); } // Paint pixel. if(nullptr != m_pfDrawPoint) { // Refresh each pixel on screen. for(int i_H=0; i_H*m_pfDrawPoint)(clsBufferedDC, i_W, i_H, m_iPixelSize); } } } _leavePaintCriticalSection(); } /*************************************************************************/ /** Function Name: SaveScreenImageToFile **/ /** Class: wxLCDBase **/ /** Accessibility: Public. **/ /** Purpose: Save current panel image to a jpeg file. **/ /** Params: **/ /** @ strFilePath[in]: Save file path. **/ /** Return: **/ /** @ true: Save successfully. **/ /** @ false: Save failed. **/ /** Notice: To support jpeg format, need add wxWidgets jpeg **/ /** format handler in initialize(OnInit) function of **/ /** the wxApp Object. **/ /** wxImage::AddHandler(new wxJPEGHandler) **/ /*************************************************************************/ bool wxLCDBase::SaveScreenImageToFile(const wxString& strFilePath) { /*----------------------------------*/ /* Variable Declaration */ /*----------------------------------*/ wxBitmap* pclsBitMap; wxMemoryDC* pclsMemoryDC; bool bReturn; /*----------------------------------*/ /* Initialize */ /*----------------------------------*/ bReturn = false; pclsMemoryDC = nullptr; /*----------------------------------*/ /* Process */ /*----------------------------------*/ // Create bitmap buffer. pclsBitMap = new wxBitmap(GetSize(), wxBITMAP_SCREEN_DEPTH); if(nullptr != pclsBitMap) { pclsMemoryDC = new wxMemoryDC(*pclsBitMap); if(nullptr != pclsMemoryDC) { bReturn = pclsMemoryDC->Blit(wxPoint(0, 0), GetSize(), &m_clsCDC, wxPoint(0, 0)); if(true == bReturn) { bReturn = pclsBitMap->SaveFile(strFilePath, wxBITMAP_TYPE_JPEG); } } } // delete pclsBitMap; delete pclsMemoryDC; return bReturn; } /*************************************************************************/ /** Function Name: CopyScreenImageToClipBoard **/ /** Class: wxLCDBase **/ /** Accessibility: Public. **/ /** Purpose: Copy current screen image to clip board. **/ /** Params: None. **/ /** Return: **/ /** @ true: Copy successfully. **/ /** @ false: Copy failed. **/ /** Notice: None. **/ /*************************************************************************/ bool wxLCDBase::CopyScreenImageToClipBoard(void) { /*----------------------------------*/ /* Variable Declaration */ /*----------------------------------*/ uint32_t uiPictureWidth, uiPictureHeight; wxBitmap* pclsDCBufferBitmap; wxMemoryDC* pclsDCBuffer; bool bReturn; /*----------------------------------*/ /* Initialize */ /*----------------------------------*/ uiPictureWidth = GetSize().GetX(); uiPictureHeight = GetSize().GetY(); pclsDCBufferBitmap = new wxBitmap(uiPictureWidth, uiPictureHeight, wxBITMAP_SCREEN_DEPTH); pclsDCBuffer = new wxMemoryDC(*pclsDCBufferBitmap); bReturn = true; /*----------------------------------*/ /* Process */ /*----------------------------------*/ if((nullptr != pclsDCBufferBitmap) && (nullptr != pclsDCBuffer)) { if(true == wxTheClipboard->Open()) { pclsDCBuffer->Blit(0, 0, uiPictureWidth, uiPictureHeight, &m_clsCDC, 0, 0); wxTheClipboard->SetData(new wxBitmapDataObject(*pclsDCBufferBitmap)); wxTheClipboard->Flush(); wxTheClipboard->Close(); } else { bReturn = false; } } delete pclsDCBufferBitmap; delete pclsDCBuffer; return bReturn; } /*************************************************************************/ /** Function Name: _freeDisplayBuffer **/ /** Class: wxLCDBase **/ /** Accessibility: Private. **/ /** Purpose: Release display buffer memory resource. **/ /** Resources: None. **/ /** Params: **/ /** @ ppuiDisplayBuffer: Display buffer pointer. **/ /** Return: None. **/ /** Notice: Private function, called when need to release a **/ /** existed display buffer. just like object destroy or **/ /** size in pixel changed. **/ /*************************************************************************/ void wxLCDBase::_freeDisplayBuffer(uint32_t** ppuiDisplayBuffer) { if(nullptr != ppuiDisplayBuffer) { for(int iIdxV=0; iIdxV 0) && (iVerticalPixelNumber > 0)) { ppuiNewDisplayBuffer = (unsigned int**)malloc(sizeof(unsigned int*)*iVerticalPixelNumber); if(nullptr != ppuiNewDisplayBuffer) { memset(ppuiNewDisplayBuffer, 0x00, sizeof(unsigned int*)*iVerticalPixelNumber); for(int iIdxV=0; iIdxV