QStandardItem* QgsMilXLibrary::addItem( QStandardItem* parent, const QString& value, const QImage& image, bool isLeaf, const QString& symbolXml, const QString& symbolMilitaryName, int symbolPointCount , bool symbolHasVariablePoints ) { QIcon icon; QSize iconSize = isLeaf ? mTreeView->iconSize() : !image.isNull() ? QSize( 32, 32 ) : QSize( 1, 32 ); QImage iconImage( iconSize, QImage::Format_ARGB32 ); iconImage.fill( Qt::transparent ); if ( !image.isNull() ) { double scale = qMin( 1., image.width() > image.height() ? iconImage.width() / double( image.width() ) : iconImage.height() / double( image.height() ) ); QPainter painter( &iconImage ); painter.setRenderHint( QPainter::SmoothPixmapTransform ); painter.drawImage( QRectF( 0.5 * ( iconSize.width() - scale * image.width() ), 0.5 * ( iconSize.height() - scale * image.height() ), scale * image.width(), scale * image.height() ), image ); } icon = QIcon( QPixmap::fromImage( iconImage ) ); if ( !parent ) { parent = mGalleryModel->invisibleRootItem(); } // Create category group item if necessary if ( !isLeaf ) { // Don't create subgroups with same text as parent if ( parent->text() == value ) { return parent; } QStandardItem* groupItem = 0; for ( int i = 0, n = parent->rowCount(); i < n; ++i ) { if ( parent->child( i )->text() == value ) { groupItem = parent->child( i ); break; } } if ( !groupItem ) { groupItem = new QStandardItem( value ); groupItem->setDragEnabled( false ); parent->setChild( parent->rowCount(), groupItem ); groupItem->setIcon( icon ); } return groupItem; } else { QStandardItem* item = new QStandardItem( QString( "%1" ).arg( symbolMilitaryName ) ); parent->setChild( parent->rowCount(), item ); item->setData( symbolXml, SymbolXmlRole ); item->setData( symbolMilitaryName, SymbolMilitaryNameRole ); item->setData( symbolPointCount, SymbolPointCountRole ); item->setData( symbolHasVariablePoints, SymbolVariablePointsRole ); item->setToolTip( item->text() ); item->setIcon( icon ); return item; } }
//This function makes a pixmap which is based on icon, but has a number painted on it. QPixmap BoxContainerItem::calcComplexPixmap(const QPixmap &icon, const QColor &fgColour, const QFont *font, const int count) { QPixmap result(icon); QPixmap numberPixmap(icon.size()); QImage iconImage(icon.convertToImage()); QImage numberImage; QRgb *rgbline; QPainter p; //Make a transparent number; first make a white number on a black background. //This pixmap also is the base alpha-channel, the foreground colour is added later. numberPixmap.fill(Qt::black); p.begin(&numberPixmap, false); p.setPen(Qt::white); if(font) p.setFont(*font); p.drawText(icon.rect(), Qt::AlignCenter, QString::number(count)); p.end(); //Convert to image and add the alpha channel. numberImage = numberPixmap.convertToImage(); if(numberImage.depth() != 32) //Make sure depth is 32 (and thus can have an alpha channel) numberImage = numberImage.convertDepth(32); numberImage.setAlphaBuffer(true); //Enable alpha channel for(int xx = 0; xx < numberImage.height(); ++xx) { rgbline = (QRgb *)numberImage.scanLine(xx); for(int yy = 0; yy < numberImage.width(); ++yy) { //Set colour and alpha channel rgbline[ yy ] = qRgba(fgColour.red(), fgColour.green(), fgColour.blue(), qRed(rgbline[ yy ])); } } //Merge icon and number and convert to result. KIconEffect::overlay(iconImage, numberImage); result.convertFromImage(iconImage); return result; }
bool IconImpl::Create(const Image& icon) { Image iconImage(icon); // Vive le COW if (!iconImage.Convert(Nz::PixelFormatType_BGRA8)) { NazaraError("Failed to convert icon to BGRA8"); return false; } auto width = iconImage.GetWidth(); auto height = iconImage.GetHeight(); ScopedXCBConnection connection; xcb_screen_t* screen = X11::XCBDefaultScreen(connection); if (!m_iconPixmap.Create( screen->root_depth, screen->root, width, height)) { NazaraError("Failed to create icon pixmap"); return false; } CallOnExit onExit([this](){ Destroy(); }); XCBGContext iconGC(connection); if (!iconGC.Create( m_iconPixmap, 0, nullptr)) { NazaraError("Failed to create icon gc"); return false; } if (!X11::CheckCookie( connection, xcb_put_image( connection, XCB_IMAGE_FORMAT_Z_PIXMAP, m_iconPixmap, iconGC, width, height, 0, 0, 0, screen->root_depth, width * height * 4, iconImage.GetConstPixels() ))) { NazaraError("Failed to put image for icon"); return false; } // Create the mask pixmap (must have 1 bit depth) std::size_t pitch = (width + 7) / 8; static std::vector<UInt8> maskPixels(pitch * height, 0); for (std::size_t j = 0; j < height; ++j) { for (std::size_t i = 0; i < pitch; ++i) { for (std::size_t k = 0; k < 8; ++k) { if (i * 8 + k < width) { UInt8 opacity = (iconImage.GetConstPixels()[(i * 8 + k + j * width) * 4 + 3] > 0) ? 1 : 0; maskPixels[i + j * pitch] |= (opacity << k); } } } } if (!m_maskPixmap.CreatePixmapFromBitmapData( X11::XCBDefaultRootWindow(connection), reinterpret_cast<uint8_t*>(&maskPixels[0]), width, height, 1, 0, 1, nullptr)) { NazaraError("Failed to create mask pixmap for icon"); return false; } onExit.Reset(); return true; }
StWinHandles::StWinHandles() #ifdef _WIN32 : ThreadWnd(0), EventMsgThread(true), hWindow(NULL), hWindowGl(NULL), hWinTmp(NULL), myMKeyStop(GlobalAddAtom(MAKEINTATOM(VK_MEDIA_STOP))), myMKeyPlay(GlobalAddAtom(MAKEINTATOM(VK_MEDIA_PLAY_PAUSE))), myMKeyPrev(GlobalAddAtom(MAKEINTATOM(VK_MEDIA_PREV_TRACK))), myMKeyNext(GlobalAddAtom(MAKEINTATOM(VK_MEDIA_NEXT_TRACK))), ThreadGL(0), hDC(NULL) { // #elif defined(__linux__) : hWindow(0), hWindowGl(0), stXDisplay(), iconImage(0), iconShape(0), xDNDRequestType(None), xDNDSrcWindow(0), xDNDVersion(0), xrandrEventBase(0), isRecXRandrEvents(false) { // #endif } StWinHandles::~StWinHandles() { close(); } void StWinHandles::glSwap() { #ifdef _WIN32 if(hDC != NULL) { SwapBuffers(hDC); } #elif defined(__linux__) if(!stXDisplay.isNull() && hRC->makeCurrent(hWindowGl)) { // if GL rendering context is bound to another drawable - we got BadMatch error glXSwapBuffers(stXDisplay->hDisplay, hWindowGl); } #endif } bool StWinHandles::glMakeCurrent() { #ifdef _WIN32 if(hDC != NULL && !hRC.isNull()) { return hRC->isCurrent(hDC) || hRC->makeCurrent(hDC); } #elif defined(__linux__) if(!stXDisplay.isNull() && !hRC.isNull()) { return hRC->makeCurrent(hWindowGl); } #endif return false; } /** * Auxiliary macros. */ #define ST_GL_ERROR_CHECK(theTrueCondition, theErrCode, theErrDesc) \ if(!(theTrueCondition)) { \ stError(theErrDesc); \ return theErrCode; \ } int StWinHandles::glCreateContext(StWinHandles* theSlave, const StRectI_t& theRect, const int theDepthSize, const bool theIsQuadStereo, const bool theDebugCtx) { #ifdef _WIN32 ThreadGL = StThread::getCurrentThreadId(); ST_DEBUG_LOG("WinAPI, glCreateContext, ThreadGL= " + ThreadGL + ", ThreadWnd= " + ThreadWnd); hDC = GetDC(hWindowGl); ST_GL_ERROR_CHECK(hDC != NULL, STWIN_ERROR_WIN32_GLDC, "WinAPI, Can't create Master GL Device Context"); if(theSlave != NULL) { theSlave->ThreadGL = ThreadGL; theSlave->hDC = GetDC(theSlave->hWindowGl); ST_GL_ERROR_CHECK(theSlave->hDC != NULL, STWIN_ERROR_WIN32_GLDC, "WinAPI, Can't create Slave GL Device Context"); } PIXELFORMATDESCRIPTOR aPixFrmtDesc = THE_PIXELFRMT_DOUBLE; aPixFrmtDesc.cDepthBits = (BYTE )theDepthSize; if(theIsQuadStereo) { aPixFrmtDesc.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_STEREO; } int aPixFrmtId = ChoosePixelFormat(hDC, &aPixFrmtDesc); ST_GL_ERROR_CHECK(aPixFrmtId != 0, STWIN_ERROR_WIN32_PIXELFORMATF, "WinAPI, Can't find a suitable PixelFormat for Master"); if(theSlave != NULL && ChoosePixelFormat(theSlave->hDC, &aPixFrmtDesc) != aPixFrmtId) { ST_ERROR_LOG("Slave window returns another pixel format! Try to ignore..."); } if(theIsQuadStereo) { DescribePixelFormat(hDC, aPixFrmtId, sizeof(PIXELFORMATDESCRIPTOR), &aPixFrmtDesc); if((aPixFrmtDesc.dwFlags & PFD_STEREO) == 0) { ST_ERROR_LOG("WinAPI, Quad Buffered stereo not supported"); } else { //bool isVistaPlus = StSys::isVistaPlus(); //bool isWin8Plus = StSys::isWin8Plus(); ///myNeedsFullscr } } HMODULE aModule = GetModuleHandleW(NULL); hWinTmp = CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE | WS_EX_NOACTIVATE, ClassTmp.toCString(), L"TmpWnd", WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED, theRect.left() + 2, theRect.top() + 2, 4, 4, NULL, NULL, aModule, NULL); ST_GL_ERROR_CHECK(hWinTmp != NULL, STWIN_ERROR_WIN32_GLDC, "WinAPI, Temporary window creation error"); HDC aDevCtxTmp = GetDC(hWinTmp); ST_GL_ERROR_CHECK(aPixFrmtId != 0, STWIN_ERROR_WIN32_PIXELFORMATF, "WinAPI, Can't find a suitable PixelFormat for Tmp"); ST_GL_ERROR_CHECK(SetPixelFormat(aDevCtxTmp, aPixFrmtId, &aPixFrmtDesc), STWIN_ERROR_WIN32_PIXELFORMATS, "WinAPI, Can't set the PixelFormat for Master"); StWinGlrcH aRendCtxTmp = new StWinGlrc(aDevCtxTmp, NULL); ST_GL_ERROR_CHECK(aRendCtxTmp->isValid(), STWIN_ERROR_WIN32_GLRC_CREATE, "WinAPI, Can't create GL Rendering Context"); ST_GL_ERROR_CHECK(aRendCtxTmp->makeCurrent(aDevCtxTmp), STWIN_ERROR_WIN32_GLRC_ACTIVATE, "WinAPI, Can't activate Tmp GL Rendering Context"); StGLContext aCtx; ST_GL_ERROR_CHECK(aCtx.stglInit(), STWIN_ERROR_WIN32_GLRC_ACTIVATE, "WinAPI, Broken Tmp GL Rendering Context"); if(aCtx.extAll->wglChoosePixelFormatARB != NULL) { const int aPixAttribs[] = { WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, WGL_SUPPORT_OPENGL_ARB, GL_TRUE, WGL_DOUBLE_BUFFER_ARB, GL_TRUE, WGL_STEREO_ARB, theIsQuadStereo ? GL_TRUE : GL_FALSE, WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, //WGL_SAMPLE_BUFFERS_ARB, 1, //WGL_SAMPLES_ARB, 8, // WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 WGL_COLOR_BITS_ARB, 24, WGL_DEPTH_BITS_ARB, theDepthSize, WGL_STENCIL_BITS_ARB, 0, 0, 0, }; unsigned int aFrmtsNb = 0; aCtx.extAll->wglChoosePixelFormatARB(hDC, aPixAttribs, NULL, 1, &aPixFrmtId, &aFrmtsNb); } ST_GL_ERROR_CHECK(SetPixelFormat(hDC, aPixFrmtId, &aPixFrmtDesc), STWIN_ERROR_WIN32_PIXELFORMATS, "WinAPI, Can't set the PixelFormat for Master"); ST_GL_ERROR_CHECK(theSlave == NULL || SetPixelFormat(theSlave->hDC, aPixFrmtId, &aPixFrmtDesc), STWIN_ERROR_WIN32_PIXELFORMATS, "WinAPI, Can't set the PixelFormat for Slave"); HGLRC aRendCtx = NULL; if(aCtx.extAll->wglCreateContextAttribsARB != NULL) { // Beware! NVIDIA drivers reject context creation when WGL_CONTEXT_PROFILE_MASK_ARB are specified // but not WGL_CONTEXT_MAJOR_VERSION_ARB/WGL_CONTEXT_MINOR_VERSION_ARB int aCtxAttribs[] = { //WGL_CONTEXT_MAJOR_VERSION_ARB, 3, //WGL_CONTEXT_MINOR_VERSION_ARB, 2, //WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, //WGL_CONTEXT_CORE_PROFILE_BIT_ARB, WGL_CONTEXT_FLAGS_ARB, theDebugCtx ? WGL_CONTEXT_DEBUG_BIT_ARB : 0, 0, 0 }; aRendCtx = aCtx.extAll->wglCreateContextAttribsARB(hDC, NULL, aCtxAttribs); } aRendCtxTmp.nullify(); destroyWindow(hWinTmp); hRC = new StWinGlrc(hDC, aRendCtx); ST_GL_ERROR_CHECK(hRC->isValid(), STWIN_ERROR_WIN32_GLRC_CREATE, "WinAPI, Can't create GL Rendering Context"); if(theSlave != NULL) { theSlave->hRC = hRC; } ST_GL_ERROR_CHECK(hRC->makeCurrent(hDC), STWIN_ERROR_WIN32_GLRC_ACTIVATE, "WinAPI, Can't activate Master GL Rendering Context"); return STWIN_INIT_SUCCESS; #elif defined(__linux__) // create an OpenGL rendering context hRC = new StWinGlrc(stXDisplay, theDebugCtx); ST_GL_ERROR_CHECK(hRC->isValid(), STWIN_ERROR_X_GLRC_CREATE, "GLX, could not create rendering context for Master"); if(theSlave != NULL) { theSlave->hRC = hRC; // bind the rendering context to the window ST_GL_ERROR_CHECK(hRC->makeCurrent(theSlave->hWindowGl), STWIN_ERROR_X_GLRC_CREATE, "GLX, Can't activate Slave GL Rendering Context"); } // bind the rendering context to the window ST_GL_ERROR_CHECK(hRC->makeCurrent(hWindowGl), STWIN_ERROR_X_GLRC_CREATE, "GLX, Can't activate Master GL Rendering Context"); return STWIN_INIT_SUCCESS; #endif }