void CRoundSliderCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { const int nMin = GetRangeMin(); const int nMax = GetRangeMax()+1; switch(nChar) { case VK_LEFT: case VK_UP: { int nNewPos = GetPos()-GetLineSize(); while(nNewPos < nMin) nNewPos += (nMax - nMin); SetPos(nNewPos); RedrawWindow(); PostMessageToParent(TB_LINEUP); } break; case VK_RIGHT: case VK_DOWN: { int nNewPos = GetPos()+GetLineSize(); while(nNewPos >= nMax) nNewPos -= (nMax - nMin); SetPos(nNewPos); RedrawWindow(); PostMessageToParent(TB_LINEDOWN); } break; case VK_PRIOR: { int nNewPos = GetPos()-GetPageSize(); while(nNewPos < nMin) nNewPos += (nMax - nMin); SetPos(nNewPos); RedrawWindow(); PostMessageToParent(TB_PAGEUP); } break; case VK_NEXT: { int nNewPos = GetPos()+GetPageSize(); while(nNewPos >= nMax) nNewPos -= (nMax - nMin); SetPos(nNewPos); RedrawWindow(); PostMessageToParent(TB_PAGEDOWN); } break; case VK_HOME: case VK_END: // Do nothing (ignore keystroke) break; default: CSliderCtrl::OnKeyDown(nChar, nRepCnt, nFlags); } }
bool wxDIB::Create(int width, int height, int depth) { // we don't support formats using palettes right now so we only create // either 24bpp (RGB) or 32bpp (RGBA) bitmaps wxASSERT_MSG( depth, wxT("invalid image depth in wxDIB::Create()") ); if ( depth < 24 ) depth = 24; // allocate memory for bitmap structures BITMAPINFO info; wxZeroMemory(info); info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); info.bmiHeader.biWidth = width; // we use positive height here which corresponds to a DIB with normal, i.e. // bottom to top, order -- normally using negative height (which means // reversed for MS and hence natural for all the normal people top to // bottom line scan order) could be used to avoid the need for the image // reversal in Create(image) but this doesn't work under NT, only Win9x! info.bmiHeader.biHeight = height; info.bmiHeader.biPlanes = 1; info.bmiHeader.biBitCount = (WORD)depth; info.bmiHeader.biSizeImage = GetLineSize(width, depth)*height; m_handle = ::CreateDIBSection ( 0, // hdc (unused with DIB_RGB_COLORS) &info, // bitmap description DIB_RGB_COLORS, // use RGB, not palette &m_data, // [out] DIB bits NULL, // don't use file mapping 0 // file mapping offset (not used here) ); if ( !m_handle ) { wxLogLastError(wxT("CreateDIBSection")); return false; } m_width = width; m_height = height; m_depth = depth; return true; }
wxImage wxDIB::ConvertToImage() const { wxCHECK_MSG( IsOk(), wxNullImage, wxT("can't convert invalid DIB to wxImage") ); // create the wxImage object const int w = GetWidth(); const int h = GetHeight(); wxImage image(w, h, false /* don't bother clearing memory */); if ( !image.Ok() ) { wxFAIL_MSG( wxT("could not allocate data for image") ); return wxNullImage; } if ( m_hasAlpha ) { image.SetAlpha(); } // this is the same loop as in Create() just above but with copy direction // reversed const int bpp = GetDepth(); const int dstBytesPerLine = w * 3; const int srcBytesPerLine = GetLineSize(w, bpp); unsigned char *dst = image.GetData() + ((h - 1) * dstBytesPerLine); unsigned char *alpha = image.HasAlpha() ? image.GetAlpha() + (h - 1)*w : NULL; const bool is32bit = bpp == 32; const unsigned char *srcLineStart = (unsigned char *)GetData(); for ( int y = 0; y < h; y++ ) { // copy one DIB line const unsigned char *src = srcLineStart; for ( int x = 0; x < w; x++ ) { dst[2] = *src++; dst[1] = *src++; dst[0] = *src++; if ( is32bit ) { if ( alpha ) { // wxImage uses non premultiplied alpha so undo // premultiplication done in Create() above const unsigned char a = *src; *alpha++ = a; if ( a > 0 ) { dst[0] = (dst[0] * 255) / a; dst[1] = (dst[1] * 255) / a; dst[2] = (dst[2] * 255) / a; } } src++; } dst += 3; } // pass to the previous line in the image dst -= 2*dstBytesPerLine; if ( alpha ) alpha -= 2*w; // and to the next one in the DIB srcLineStart += srcBytesPerLine; } return image; }
bool wxDIB::Create(const wxImage& image) { wxCHECK_MSG( image.Ok(), false, wxT("invalid wxImage in wxDIB ctor") ); const int h = image.GetHeight(); const int w = image.GetWidth(); // if we have alpha channel, we need to create a 32bpp RGBA DIB, otherwise // a 24bpp RGB is sufficient m_hasAlpha = image.HasAlpha(); const int bpp = m_hasAlpha ? 32 : 24; if ( !Create(w, h, bpp) ) return false; // DIBs are stored in bottom to top order (see also the comment above in // Create()) so we need to copy bits line by line and starting from the end const int srcBytesPerLine = w * 3; const int dstBytesPerLine = GetLineSize(w, bpp); const unsigned char *src = image.GetData() + ((h - 1) * srcBytesPerLine); const unsigned char *alpha = m_hasAlpha ? image.GetAlpha() + (h - 1)*w : NULL; unsigned char *dstLineStart = (unsigned char *)m_data; for ( int y = 0; y < h; y++ ) { // copy one DIB line unsigned char *dst = dstLineStart; if ( alpha ) { for ( int x = 0; x < w; x++ ) { // RGB order is reversed, and we need to premultiply // all channels by alpha value for use with ::AlphaBlend. const unsigned char a = *alpha++; *dst++ = (unsigned char)((src[2] * a + 127) / 255); *dst++ = (unsigned char)((src[1] * a + 127) / 255); *dst++ = (unsigned char)((src[0] * a + 127) / 255); *dst++ = a; src += 3; } } else // no alpha channel { for ( int x = 0; x < w; x++ ) { // RGB order is reversed. *dst++ = src[2]; *dst++ = src[1]; *dst++ = src[0]; src += 3; } } // pass to the previous line in the image src -= 2*srcBytesPerLine; if ( alpha ) alpha -= 2*w; // and to the next one in the DIB dstLineStart += dstBytesPerLine; } return true; }
void wxSlider::SetPageSize( int pageSize ) { GTKDisableEvents(); gtk_range_set_increments(GTK_RANGE (m_scale), GetLineSize(), pageSize); GTKEnableEvents(); }
wxImage wxDIB::ConvertToImage() const { wxCHECK_MSG( IsOk(), wxNullImage, wxT("can't convert invalid DIB to wxImage") ); // create the wxImage object const int w = GetWidth(); const int h = GetHeight(); wxImage image(w, h, false /* don't bother clearing memory */); if ( !image.IsOk() ) { wxFAIL_MSG( wxT("could not allocate data for image") ); return wxNullImage; } const int bpp = GetDepth(); // Remember if we have any "real" transparency, i.e. either any partially // transparent pixels or not all pixels are fully opaque or fully // transparent. bool hasAlpha = false; bool hasOpaque = false; bool hasTransparent = false; if ( bpp == 32 ) { // 32 bit bitmaps may be either 0RGB or ARGB and we don't know in // advance which one do we have so suppose we have alpha of them and // get rid of it later if it turns out we didn't. image.SetAlpha(); } // this is the same loop as in Create() just above but with copy direction // reversed const int dstBytesPerLine = w * 3; const int srcBytesPerLine = GetLineSize(w, bpp); unsigned char *dst = image.GetData() + ((h - 1) * dstBytesPerLine); unsigned char *alpha = image.HasAlpha() ? image.GetAlpha() + (h - 1)*w : NULL; const unsigned char *srcLineStart = (unsigned char *)GetData(); for ( int y = 0; y < h; y++ ) { // copy one DIB line const unsigned char *src = srcLineStart; for ( int x = 0; x < w; x++ ) { dst[2] = *src++; dst[1] = *src++; dst[0] = *src++; if ( bpp == 32 ) { // wxImage uses non premultiplied alpha so undo // premultiplication done in Create() above const unsigned char a = *src; *alpha++ = a; // Check what kind of alpha do we have. switch ( a ) { case 0: hasTransparent = true; break; default: // Anything in between means we have real transparency // and must use alpha channel. hasAlpha = true; break; case 255: hasOpaque = true; break; } if ( a > 0 ) { dst[0] = (dst[0] * 255) / a; dst[1] = (dst[1] * 255) / a; dst[2] = (dst[2] * 255) / a; } src++; } dst += 3; } // pass to the previous line in the image dst -= 2*dstBytesPerLine; if ( alpha ) alpha -= 2*w; // and to the next one in the DIB srcLineStart += srcBytesPerLine; } if ( hasOpaque && hasTransparent ) hasAlpha = true; if ( !hasAlpha && image.HasAlpha() ) image.ClearAlpha(); return image; }
bool wxDIB::Create(const wxImage& image, PixelFormat pf) { wxCHECK_MSG( image.IsOk(), false, wxT("invalid wxImage in wxDIB ctor") ); const int h = image.GetHeight(); const int w = image.GetWidth(); // if we have alpha channel, we need to create a 32bpp RGBA DIB, otherwise // a 24bpp RGB is sufficient const bool hasAlpha = image.HasAlpha(); const int bpp = hasAlpha ? 32 : 24; if ( !Create(w, h, bpp) ) return false; // DIBs are stored in bottom to top order (see also the comment above in // Create()) so we need to copy bits line by line and starting from the end const int srcBytesPerLine = w * 3; const int dstBytesPerLine = GetLineSize(w, bpp); const unsigned char *src = image.GetData() + ((h - 1) * srcBytesPerLine); const unsigned char *alpha = hasAlpha ? image.GetAlpha() + (h - 1)*w : NULL; unsigned char *dstLineStart = (unsigned char *)m_data; for ( int y = 0; y < h; y++ ) { // Copy one DIB line. Note that RGB components order is reversed in // Windows bitmaps compared to wxImage and is actually BGR. unsigned char *dst = dstLineStart; if ( alpha ) { int x; switch ( pf ) { case PixelFormat_PreMultiplied: // Pre-multiply pixel values so that the DIB could be used // with ::AlphaBlend(). for ( x = 0; x < w; x++ ) { const unsigned char a = *alpha++; *dst++ = (unsigned char)((src[2] * a + 127) / 255); *dst++ = (unsigned char)((src[1] * a + 127) / 255); *dst++ = (unsigned char)((src[0] * a + 127) / 255); *dst++ = a; src += 3; } break; case PixelFormat_NotPreMultiplied: // Just copy pixel data without changing it. for ( x = 0; x < w; x++ ) { *dst++ = src[2]; *dst++ = src[1]; *dst++ = src[0]; *dst++ = *alpha++; src += 3; } break; } } else // no alpha channel { for ( int x = 0; x < w; x++ ) { *dst++ = src[2]; *dst++ = src[1]; *dst++ = src[0]; src += 3; } } // pass to the previous line in the image src -= 2*srcBytesPerLine; if ( alpha ) alpha -= 2*w; // and to the next one in the DIB dstLineStart += dstBytesPerLine; } return true; }
void wxSlider::SetPageSize( int pageSize ) { BlockScrollEvent(); gtk_range_set_increments(GTK_RANGE (m_widget), GetLineSize(), pageSize); UnblockScrollEvent(); }