cv::Mat draw(int id, int cellSize, bool withMargin, cv::Scalar color) const { // Creating the image of the bit matrix static const int DATA_SIZE = 6; cv::Size dataDim(DATA_SIZE,DATA_SIZE); unsigned char dataMatrix[DATA_SIZE*DATA_SIZE]; mDecode.getCodec().getTagEncodedId(id, dataMatrix); cv::Mat dataImage(dataDim, CV_8U, dataMatrix); // Adding the black border arounf the bit matrix cv::Size borderSize(2,2); cv::Mat tagImage(dataImage.size()+borderSize*2, CV_8U, cv::Scalar(0)); dataImage.copyTo(tagImage(cv::Rect(borderSize, dataImage.size()))); // Adding the optionnal white margin cv::Size marginSize(0,0); if (withMargin) marginSize += borderSize; cv::Mat outlinedImage(tagImage.size()+marginSize*2, CV_8U, cv::Scalar(1)); tagImage.copyTo(outlinedImage(cv::Rect(marginSize, tagImage.size()))); // Resizing to specified cellSize cv::Mat sizedImage(outlinedImage.size()*cellSize, CV_8U); cv::resize(outlinedImage, sizedImage, sizedImage.size(), 0, 0, cv::INTER_NEAREST); // Coloring cv::Mat redImage = (1-sizedImage)*color[0]+sizedImage*255; cv::Mat greenImage = (1-sizedImage)*color[1]+sizedImage*255; cv::Mat blueImage = (1-sizedImage)*color[2]+sizedImage*255; cv::Mat colorImage(sizedImage.size(), CV_8UC3); cv::merge(std::vector<cv::Mat>{blueImage, greenImage, redImage}, colorImage); return colorImage; }
Vec2f AbsoluteLayout::layoutSize(const MFUnrecChildComponentPtr* Components, const Component* ParentComponent, SizeType TheSizeType) const { Vec2f Result(0.0,0.0); Pnt2f borderTopLeft, borderBottomRight; dynamic_cast<const ComponentContainer*>(ParentComponent)->getInsideInsetsBounds(borderTopLeft, borderBottomRight); Vec2f borderSize(borderBottomRight-borderTopLeft); Vec2f ComponentSize; Pnt2f ComponentPosition; for(UInt32 i(0) ; i<Components->size() ; ++i) { ComponentPosition = dynamic_cast<AbsoluteLayoutConstraints*>((*Components)[i]->getConstraints())->getPosition(); ComponentSize = getComponentSize((*Components)[i],TheSizeType); if(ComponentPosition.x() + ComponentSize.x() > Result.x()) { Result[0] = ComponentPosition.x() + ComponentSize.x(); } if(ComponentPosition.y() + ComponentSize.y() > Result.y()) { Result[1] = ComponentPosition.y() + ComponentSize.y(); } } return Result; }
void GridLayout::updateLayout(const MFUnrecComponentPtr* Components, const Component* ParentComponent) const { Pnt2f borderTopLeft, borderBottomRight; dynamic_cast<const ComponentContainer*>(ParentComponent)->getInsideInsetsBounds(borderTopLeft, borderBottomRight); Vec2f borderSize(borderBottomRight-borderTopLeft); Real32 Xpos = 0; Real32 Ypos = 0; Real32 maxSizeX = 0; Real32 maxSizeY = 0; Real32 debug = 10; Int32 numComp = Components->getSize(); Real32 buttonXSize, buttonYSize; //set the size to the perfered sizes for the buttons for(UInt16 i = 0; i<Components->size(); i++){ if ((*Components)[i] != NULL) { if((*Components)[i]->getPreferredSize().x()>maxSizeX) maxSizeX = (*Components)[i]->getPreferredSize().x(); if((*Components)[i]->getPreferredSize().y()>maxSizeY) maxSizeY = (*Components)[i]->getPreferredSize().y(); } } //set the size of the button for(UInt16 i = 0; i < Components->size(); i++){ if ((*Components)[i] != NULL) { if(maxSizeX < (*Components)[i]->getMaxSize().x()) buttonXSize = maxSizeX; else buttonXSize = (*Components)[i]->getMaxSize().x(); if(maxSizeY<(*Components)[i]->getMaxSize().y()) buttonYSize = maxSizeY; else buttonYSize = (*Components)[i]->getMaxSize().y(); (*Components)[i]->setSize(Vec2f(buttonXSize, buttonYSize)); } } //position each button for(UInt16 i = 0; i <= getRows()&& numComp>=0; i++){ if ((*Components)[i] != NULL) { for(UInt16 j = 0; j < getColumns()&& numComp>0; j++){ debug = i*getColumns()+j; (*Components)[i*getColumns()+j]->setPosition(borderTopLeft + Vec2f(Xpos, Ypos)); numComp--; Xpos = Xpos + (maxSizeX+getHorizontalGap()); } Xpos = 0; Ypos += maxSizeY+getVerticalGap(); } } }
void CardLayout::updateLayout(const MFUnrecChildComponentPtr* Components, const Component* ParentComponent) const { if(getCard() >= Components->size()) { SWARNING << "CardLayout::updateLayout: The Index set for Card is: "<< getCard() << ", but there are only " << Components->size() << " components in the container this layout is attached to" << std::endl; return; } /*! Draw the current "card" component centered in the parent component and set to the size of the parent component, or to its max size */ Pnt2f borderTopLeft, borderBottomRight; dynamic_cast<const ComponentContainer*>(ParentComponent)->getInsideInsetsBounds(borderTopLeft, borderBottomRight); Vec2f borderSize(borderBottomRight-borderTopLeft); Vec2f size(borderSize),offset; ComponentRefPtr curCard((*Components)[getCard()]); for(UInt32 i(0) ; i<Components->size() ; ++i) { if((*Components)[i] != curCard && (*Components)[i]->getSize() != Vec2f(0.0f,0.0f)) { (*Components)[i]->setSize(Vec2f(0.0f,0.0f)); } } // check each dimension against the max size of the component; if (size[0] > curCard->getMaxSize()[0]) size[0] = curCard->getMaxSize()[0]; if (size[1] > curCard->getMaxSize()[1]) size[1] = curCard->getMaxSize()[1]; // set the component to its parent component's size, or its max size if(curCard->getSize() != size) { curCard->setSize(size); } offset[0] = (borderSize.x()-size.x())/2; offset[1] = (borderSize.y()-size.y())/2; Pnt2f Pos(borderTopLeft + Vec2f(offset)); if(curCard->getPosition() != Pos) { curCard->setPosition(Pos); } }
void GeoWidgetBubble::paint( GeoPainter* painter, const ViewportParams* viewport ) { Q_UNUSED( viewport ); if( !m_widgetInitialized && ( m_widget!=0) ) { QWidget *widget = dynamic_cast<QWidget*>( painter->device() ); if ( widget ) { setParentWidget( widget ); } } if( !m_hidden ) { if ( m_widgetInitialized ) { m_widget->setVisible( true ); QSize widgetSize = m_widget->size(); //how wide and high the border is //sum of both sides of the border QSize borderSize( 40, 40 ); QPoint borderOffset( -10, -10 ); //position of the bubble QPoint position = m_screenPosition + m_offset; m_widget->move( position ) ; painter->save(); //draw the border painter->setPen( QPen( Oxygen::aluminumGray4 ) ); painter->setBrush( QBrush( QColor( 255, 255, 255) , Qt::SolidPattern )); painter->drawRoundedRect( QRect( position + borderOffset, widgetSize + borderSize ), 10, 10 ); painter->restore(); } } else { m_widget->hide(); } }
void OverlayLayout::updateLayout(const MFUnrecComponentPtr* Components, const Component* ParentComponent) const { Pnt2f borderTopLeft, borderBottomRight; dynamic_cast<const ComponentContainer*>(ParentComponent)->getInsideInsetsBounds(borderTopLeft, borderBottomRight); Vec2f borderSize(borderBottomRight-borderTopLeft); int maxX = 0; int maxY = 0; for(UInt32 i = 0; i < Components->size(); i++){ (*Components)[i]->setSize((*Components)[i]->getPreferredSize()); if((*Components)[i]->getSize().x()>maxX) maxX = (*Components)[i]->getSize().x(); if((*Components)[i]->getSize().y()>maxY) maxY = (*Components)[i]->getSize().y(); } //overlay layout simply draws all the components on top of each other, with the reference point for all the components being the same for(UInt32 i = 0; i <Components->size(); i++){ //(*Components)[i]->setSize((*Components)[i]->getPreferredSize()); (*Components)[i]->setPosition(borderTopLeft + Vec2f((maxX-(*Components)[i]->getSize().x())/2.0, (maxY-(*Components)[i]->getSize().y())/2.0)); } }
int main ( int argc, char **argv ) { int intervals=5; int octave=0; /*CvCapture *capture; capture = cvCreateFileCapture("/users/eleves-a/x2008/benoit.seguin/INF560/Projet/cuda.avi"); if (!capture) { printf("Ouverture du flux vidéo impossible !\n"); return 1; } IplImage *img = cvQueryFrame(capture);*/ IplImage *img = cvLoadImage("image1.jpg"); uint width=img->width; uint height=img->height; IplImage *imgGrayscale = cvCreateImage( cvSize( width, height ), IPL_DEPTH_8U, 1 ); cvCvtColor( img, imgGrayscale, CV_RGB2GRAY ); //initialisation de la memoire CUDA CUDAinit(imgGrayscale->width,imgGrayscale->height,intervals); //initialisation des variables char s[255]; clock_t totaltime; IplImage *integral = cvCreateImage(cvSize(imgGrayscale->width,imgGrayscale->height),IPL_DEPTH_32S,1); IplImage *imgs[intervals]; IplImage *imgsShow[intervals]; for(int i=0; i<intervals; i++) { imgs[i]=cvCreateImage(cvSize(imgGrayscale->width,imgGrayscale->height),IPL_DEPTH_32S,1); imgsShow[i]=cvCreateImage(cvSize(imgGrayscale->width,imgGrayscale->height),IPL_DEPTH_32S,1); } //initialisation de la boucle makeIntegralImage(imgGrayscale,integral); CUDAcalculateGaussianDerivative(integral,octave,intervals); //boucle de traitement for(int frame=1; frame<=90; frame++) { totaltime=clock(); sprintf(s,"image%i.jpg",frame); img = cvLoadImage(s); cvCvtColor( img, imgGrayscale, CV_RGB2GRAY ); //integralImage clock_t timer=clock(); makeIntegralImage(imgGrayscale,integral); std::cout << "integrale : " << 1000*(float)(clock()-timer)/(float)CLOCKS_PER_SEC <<"ms"<< std::endl; // for(int i=1;i<img->height;i++){ // for(int j=1;j<img->width;j++){ // i=j; // //if(((int*)( imgs[0]->imageData + imgs[0]->widthStep * i)) [j] != ((int*)( imgs2[0]->imageData + imgs2[0]->widthStep * i)) [j]) // std::cout << i << "," << j << " "<< (int)((uchar*)( (img->imageData) + (img->widthStep) * i)) [j]<< " "<< getPixel(img2,i,j)+getPixel(img2,i-1,j-1)-getPixel(img2,i-1,j)-getPixel(img2,i,j-1) << std::endl; // } // } //filtres gaussiens timer=clock(); CUDAretrieveGaussianDerivative(imgs,intervals); CUDAcalculateGaussianDerivative(integral,octave,intervals); //calculateGaussianDerivative(integral,imgs,octave,intervals); std::cout << "calculateGaussianDerivative : " << 1000*(float)(clock()-timer)/(float)CLOCKS_PER_SEC <<"ms"<< std::endl; //recherche d'extremas timer=clock(); std::list<std::vector<int> > maxs(findExtrema(imgs,intervals)); std::cout << "findExtrema : " << 1000*(float)(clock()-timer)/(float)CLOCKS_PER_SEC <<"ms"<< std::endl; std::cout << "tmps total avt affichage : " << 1000*(float)(clock()-totaltime)/(float)CLOCKS_PER_SEC <<"ms"<< std::endl; //affichage //cvShowImage( "Integrale", img2 ); std::list<vector<int> >::iterator tmp=maxs.begin(); for (int i = 0; i < intervals; ++i) { cvScale(imgs[i],imgsShow[i],100); while(tmp!=maxs.end() && (*tmp)[0]==i) { cvCircle(imgsShow[i], cvPoint((*tmp)[2],(*tmp)[1]), borderSize(octave,i), cvScalar(0,255,0), 1); cvCircle(img, cvPoint((*tmp)[2],(*tmp)[1]), borderSize(octave,i), cvScalar(0,255,0), 2); tmp++; } sprintf(s,"%i",i); cvShowImage( s, imgsShow[i] ); } cvShowImage( "Image originale", img ); cvWaitKey(); } //FIN cvWaitKey(); cvReleaseImage(&imgGrayscale); cvReleaseImage(&integral); //cvReleaseCapture(&capture); CUDAclose(intervals); return 0; }
void FlowLayout::updateLayout(const MFUnrecComponentPtr* Components, const Component* ParentComponent) const { /*! totalMajorAxis will hold the width of its container, and cumMajorAxis will hold the width of all of the buttons. That way it will always know when to move to the next line. In addition, maxMinorAxis keeps track of the largest height so it knows how far down to move the next row. Also, oneInRow is used to make sure that it places at least one component in every row. */ UInt32 AxisIndex(0); if(getOrientation() != HORIZONTAL_ORIENTATION ) AxisIndex = 1; Vec2f gap(getHorizontalGap(), getVerticalGap()); UInt32 numGaps(0); /*! When finding the cumMinor Axis, the gap is included, because there is no count for how many stacks there are. When finding cumMajor, the gap isn't included because the total distance relies on how many components there are in that row/column. */ Pnt2f borderTopLeft, borderBottomRight; dynamic_cast<const ComponentContainer*>(ParentComponent)->getInsideInsetsBounds(borderTopLeft, borderBottomRight); Vec2f borderSize(borderBottomRight-borderTopLeft); Real64 totalMajorAxis(borderSize[AxisIndex]); Real32 cumMajorAxis(0); Real32 maxMinorAxis(0); Real32 cumMinorAxis(0); Real32 prevComponent(0); Real64 offsetMajorAxis(0); Real64 offsetMinorAxis(0); Real64 offsetX(borderTopLeft.x()); Real64 offsetY(borderTopLeft.y()); bool firstOne = true; for(UInt32 i=0 ; i<Components->size(); ++i) { } for(UInt32 i=0 ; i<Components->size(); ++i) { // set the component to its preferred size (*Components)[i]->setSize(getAppropriateComponentSize((*Components)[i])); // if there is only one so far, then it can't draw it using cumMajorAxis // because it hasn't been set yet if (firstOne) // this one might draw it { firstOne = false; // if this is the last component or it is already too big for the // container, draw it centered on its line if (i == Components->size() || (*Components)[i]->getSize()[AxisIndex] >= totalMajorAxis) { // find how far to translate to make it properly aligned offsetMajorAxis = getMajorAxisAlignment()*(totalMajorAxis - (*Components)[i]->getSize()[AxisIndex]); if (AxisIndex) { offsetY+= offsetMajorAxis; } else { offsetX += offsetMajorAxis; } (*Components)[i]->setPosition(Pnt2f(offsetX, offsetY)); // get to the next row if (AxisIndex) { offsetX += (*Components)[i]->getSize()[(AxisIndex+1)%2]+gap[(AxisIndex+1)%2]; offsetY += -offsetMajorAxis; } else { offsetX += -offsetMajorAxis; offsetY += (*Components)[i]->getSize()[(AxisIndex+1)%2]+gap[(AxisIndex+1)%2]; } // update cumMinorAxis, other values should still be at 0 cumMinorAxis += (*Components)[i]->getSize()[(AxisIndex+1)%2]; if(i < Components->size()-1) { cumMinorAxis += gap[(AxisIndex+1)%2]; } // update prevComponent prevComponent++; // next component is still just like the first one firstOne = true; } else { // update the maxMinorAxis maxMinorAxis = (*Components)[i]->getSize()[(AxisIndex+1)%2]; // update cumMajorAxis cumMajorAxis += (*Components)[i]->getSize()[AxisIndex]; } } else if (cumMajorAxis + (*Components)[i]->getSize()[AxisIndex] + gap[AxisIndex]*(i-prevComponent) > totalMajorAxis) // this one draws up to i { // The numGaps is one less than the number of components being drawn, but it // is actually translates once for each component, so it must be compensated // when returning to the next row. numGaps = i-prevComponent-1; // find how far to translate to make it properly aligned offsetMajorAxis = getMajorAxisAlignment()*(totalMajorAxis - (cumMajorAxis+numGaps*gap[AxisIndex])); if (AxisIndex){ offsetY += offsetMajorAxis; } else { offsetX += offsetMajorAxis; } for (int j = prevComponent; j < i; j++) { // find how far to translate to make this button properly aligned offsetMinorAxis = (maxMinorAxis-(*Components)[j]->getSize()[(AxisIndex+1)%2])*getComponentAlignment(); // translate to make it properly aligned if (AxisIndex) { offsetX += offsetMinorAxis; } else { offsetY += offsetMinorAxis; } (*Components)[j]->setPosition(Pnt2f(offsetX, offsetY)); // translate to next button if (AxisIndex) { offsetX+=-(Real64)offsetMinorAxis; offsetY+= (*Components)[j]->getSize()[AxisIndex] + gap[AxisIndex]; } else { offsetX+=(*Components)[j]->getSize()[AxisIndex] + gap[AxisIndex]; offsetY+= -offsetMinorAxis; } } // translate to the next row if (AxisIndex) { offsetX += maxMinorAxis+gap[(AxisIndex+1)%2]; offsetY += -(offsetMajorAxis+cumMajorAxis+(numGaps+1)*gap[AxisIndex]); } else { offsetX += -(offsetMajorAxis+cumMajorAxis+(numGaps+1)*gap[AxisIndex]); offsetY += maxMinorAxis+gap[(AxisIndex+1)%2]; } cumMinorAxis += maxMinorAxis + gap[(AxisIndex+1)%2]; maxMinorAxis = (*Components)[i]->getSize()[(AxisIndex+1)%2]; prevComponent = i; cumMajorAxis = (*Components)[i]->getSize()[AxisIndex]; } else { // update the maxMinorAxis if ((*Components)[i]->getSize()[(AxisIndex+1)%2] > maxMinorAxis) maxMinorAxis = (*Components)[i]->getSize()[(AxisIndex+1)%2]; // update cumMajorAxis cumMajorAxis += (*Components)[i]->getSize()[AxisIndex]; } if (i+1 == Components->size() && !firstOne) // if on the last one, draw the last buttons { numGaps = i-prevComponent; // find how far to translate to make it properly aligned offsetMajorAxis = getMajorAxisAlignment()*(totalMajorAxis - (cumMajorAxis+numGaps*gap[AxisIndex])); if (AxisIndex) { offsetY += offsetMajorAxis; } else { offsetX += offsetMajorAxis; } for (int j = prevComponent; j < i+1; j++) { // find how far to translate to make this button properly aligned offsetMinorAxis = (maxMinorAxis-(*Components)[j]->getSize()[(AxisIndex+1)%2])*getComponentAlignment(); // translate to make it properly aligned if (AxisIndex) { offsetX += offsetMinorAxis; } else { offsetY += offsetMinorAxis; } (*Components)[j]->setPosition(Pnt2f(offsetX, offsetY)); if (AxisIndex) { offsetX += -(Real64)offsetMinorAxis; offsetY += (*Components)[j]->getSize()[AxisIndex] + gap[AxisIndex]; } else { offsetX += (*Components)[j]->getSize()[AxisIndex] + gap[AxisIndex]; offsetY+= -(Real64)offsetMinorAxis; } } // translate to the next row if (AxisIndex) { offsetX += maxMinorAxis+gap[(AxisIndex+1)%2]; offsetY += -(offsetMajorAxis+cumMajorAxis+(numGaps+1)*gap[AxisIndex]); } else { offsetX += -(offsetMajorAxis+cumMajorAxis+(numGaps+1)*gap[AxisIndex]); offsetY += maxMinorAxis+gap[(AxisIndex+1)%2]; } cumMinorAxis += maxMinorAxis; } } //Minor Axis Alignment Real32 displacement(borderSize[(AxisIndex+1)%2]-cumMinorAxis); Pnt2f offset; displacement *= getMinorAxisAlignment(); for (UInt32 i = 0; i < Components->size(); ++i) { offset = (*Components)[i]->getPosition(); offset[(AxisIndex+1)%2] += displacement; (*Components)[i]->setPosition(offset); } for(UInt32 i=0 ; i<Components->size(); ++i) { } }
/////////////////////////////////////////////////////////// // Function type: I/O // Contributors: Pokedude // Last edit by: Pokedude // Date of edit: 6/11/2016 // /////////////////////////////////////////////////////////// bool MapHeader::read(const qboy::Rom &rom, UInt32 offset) { if (!rom.seek(offset)) AME_THROW(HDR_ERROR_OFFSET, rom.redirected()); // Reads the map's dimensions m_Width = rom.readWord(); m_Height = rom.readWord(); // Reads all the pointers within the structure m_PtrBorder = rom.readPointerRef(); m_PtrBlocks = rom.readPointer(); m_PtrPrimary = rom.readPointerRef(); m_PtrSecondary = rom.readPointerRef(); // Determines whether these pointers are valid if (!rom.checkOffset(m_PtrBorder)) AME_THROW(HDR_ERROR_BORDER, offset + 8); if (!rom.checkOffset(m_PtrBlocks)) AME_THROW(HDR_ERROR_BLOCKS, offset + 12); if (!rom.checkOffset(m_PtrPrimary)) AME_THROW(HDR_ERROR_PRIMARY, offset + 16); if (!rom.checkOffset(m_PtrSecondary)) AME_THROW(HDR_ERROR_SECONDARY, offset + 20); // Retrieves the border (different between games!) if (rom.info().isFRLG()) { QSize borderSize(rom.readByte(), rom.readByte()); m_Border.read(rom, m_PtrBorder, borderSize); } else { m_Border.read(rom, m_PtrBorder, QSize(2, 2)); } // Retrieves the map block data rom.seek(m_PtrBlocks); for (unsigned i = 0; i < m_Width * m_Height; i++) { MapBlock *block = new MapBlock; UInt16 data = rom.readHWord(); block->block = (data & 0x3FF); block->permission = (data >> 0xA); m_Blocks.push_back(block); } // Loads the tilesets, if necessary if ((m_Primary = TilesetManager::get(m_PtrPrimary)) == NULL) { m_Primary = new Tileset; m_Primary->read(rom, m_PtrPrimary); TilesetManager::add(m_Primary); } if ((m_Secondary = TilesetManager::get(m_PtrSecondary)) == NULL) { m_Secondary = new Tileset; m_Secondary->read(rom, m_PtrSecondary); TilesetManager::add(m_Secondary); } // Loading successful return true; }
void BorderLayout::updateLayout(const MFUnrecChildComponentPtr* Components, const Component* ParentComponent) const { Pnt2f borderTopLeft, borderBottomRight; dynamic_cast<const ComponentContainer*>(ParentComponent)->getInsideInsetsBounds(borderTopLeft, borderBottomRight); Vec2f borderSize(borderBottomRight-borderTopLeft); Real32 NorthHeight(0); Real32 SouthHeight(0); Real32 WestWidth(0); Real32 EastWidth(0); Vec2f size; Vec2f offset; // the first pass through gets some crucial dimensions to determine // the sizes of the buttons for(UInt32 i = 0 ; i<Components->size(); ++i) { if((*Components)[i]->getConstraints() != NULL) { switch (dynamic_cast<BorderLayoutConstraints*>((*Components)[i]->getConstraints())->getRegion()) { // don't need to do anything with the center quite yet case BorderLayoutConstraints::BORDER_NORTH: NorthHeight = (*Components)[i]->getPreferredSize().y(); break; case BorderLayoutConstraints::BORDER_EAST: EastWidth = (*Components)[i]->getPreferredSize().x(); break; case BorderLayoutConstraints::BORDER_SOUTH: SouthHeight = (*Components)[i]->getPreferredSize().y(); break; case BorderLayoutConstraints::BORDER_WEST: WestWidth = (*Components)[i]->getPreferredSize().x(); break; default: break; } } } Pnt2f Pos; // this second pass sets its size and draws them for(UInt32 i = 0 ; i<Components->size(); ++i) { // Find its region and draw it accordingly if((*Components)[i]->getConstraints() != NULL) { switch (dynamic_cast<BorderLayoutConstraints*>((*Components)[i]->getConstraints())->getRegion()) { case BorderLayoutConstraints::BORDER_CENTER: // set up the size of the button and its extra displacement if ((*Components)[i]->getMaxSize().x() < borderSize.x()-(WestWidth+EastWidth)) { size[0] = (*Components)[i]->getMaxSize().x(); offset[0] = (borderSize.x()-(WestWidth+EastWidth)-size[0])/2 + WestWidth; } else { size[0] = borderSize.x()-(WestWidth+EastWidth); offset[0] = WestWidth; } if ((*Components)[i]->getMaxSize().y() < borderSize.y()-(NorthHeight+SouthHeight)) { size[1] = (*Components)[i]->getMaxSize().y(); offset[1] = (borderSize.y()-(NorthHeight+SouthHeight)-size[1])/2 + NorthHeight; } else { size[1] = borderSize.y()-(NorthHeight+SouthHeight); offset[1] = NorthHeight; } break; case BorderLayoutConstraints::BORDER_NORTH: // set up the size of the button and its extra displacement size[1] = (*Components)[i]->getPreferredSize().y(); offset[1] = 0; if ((*Components)[i]->getMaxSize().x() < borderSize.x()) { size[0] = (*Components)[i]->getMaxSize().x(); offset[0] = (borderSize.x()-size[0])/2; } else { size[0] = borderSize.x(); offset[0] = 0; } break; case BorderLayoutConstraints::BORDER_EAST: // set up the size of the button and its extra displacement size[0] = (*Components)[i]->getPreferredSize().x(); offset[0] = borderSize.x()-size.x(); if ((*Components)[i]->getMaxSize().y() < borderSize.y()-(NorthHeight+SouthHeight)) { size[1] = (*Components)[i]->getMaxSize().y(); offset[1] = (borderSize.y()-size[1]-(NorthHeight+SouthHeight))/2+NorthHeight; } else { size[1] = borderSize.y()-(NorthHeight+SouthHeight); offset[1] = NorthHeight; } break; case BorderLayoutConstraints::BORDER_SOUTH: // set up the size of the button and its extra displacement size[1] = (*Components)[i]->getPreferredSize().y(); offset[1] = borderSize.y()-size[1]; if ((*Components)[i]->getMaxSize().x() < borderSize.x()) { size[0] = (*Components)[i]->getMaxSize().x(); offset[0] = (borderSize.x()-size[0])/2; } else { size[0] = borderSize.x(); offset[0] = 0; } break; case BorderLayoutConstraints::BORDER_WEST: // set up the size of the button and its extra displacement size[0] = (*Components)[i]->getPreferredSize().x(); offset[0] = 0; if ((*Components)[i]->getMaxSize().y() < borderSize.y()-(NorthHeight+SouthHeight)) { size[1] = (*Components)[i]->getMaxSize().y(); offset[1] = (borderSize.y()-size[1]-(NorthHeight+SouthHeight))/2 + NorthHeight; } else { size[1] = borderSize.y()-(NorthHeight+SouthHeight); offset[1] = NorthHeight; } break; default: // if it isn't any of the regions, set it up to not be drawn size[0] = size[1] = offset[0] = offset[1] = 0; break; } size[0] = osgMin(osgMax(size[0], (*Components)[i]->getMinSize().x()), (*Components)[i]->getMaxSize().x()); size[1] = osgMin(osgMax(size[1], (*Components)[i]->getMinSize().y()), (*Components)[i]->getMaxSize().y()); // now set the position and size of the button if((*Components)[i]->getSize() != size) { (*Components)[i]->setSize(size); } Pos = borderTopLeft + Vec2f(offset); if((*Components)[i]->getPosition() != Pos) { (*Components)[i]->setPosition(Pos); } } } }
bool QtCurveHandler::readConfig(bool compositingToggled) { QtCurveConfig oldConfig=m_config; KConfig configFile("kwinqtcurverc"); const KConfigGroup config(&configFile, "General"); QFontMetrics fm(m_titleFont); // active font = inactive font int oldSize=m_titleHeight, oldToolSize=m_titleHeightTool; bool changedBorder=false; // The title should stretch with bigger font sizes! m_titleHeight = qMax(16, fm.height() + 4); // 4 px for the shadow etc. // have an even title/button size so the button icons are fully centered... if (m_titleHeight%2 == 0) m_titleHeight++; fm = QFontMetrics(m_titleFontTool); // active font = inactive font // The title should stretch with bigger font sizes! m_titleHeightTool = qMax(13, fm.height()); // don't care about the shadow etc. // have an even title/button size so the button icons are fully centered... if (m_titleHeightTool%2 == 0) m_titleHeightTool++; m_config.load(&configFile); #if KDE_IS_VERSION(4, 3, 85) static bool borderHack=false; if(borderHack) { m_config.setOuterBorder(KWindowSystem::compositingActive() ? QtCurveConfig::SHADE_NONE : (m_config.customShadows() ? QtCurveConfig::SHADE_SHADOW : QtCurveConfig::SHADE_DARK)); changedBorder=true; borderHack=false; } else if(compositingToggled && !m_config.outerBorder() && (m_config.borderSize()<QtCurveConfig::BORDER_TINY || (wStyle()->pixelMetric((QStyle::PixelMetric)QtC_WindowBorder, 0L, 0L)&WINDOW_BORDER_COLOR_TITLEBAR_ONLY))) { QDBusConnection::sessionBus().send(QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig")); borderHack=true; } #endif m_titleHeight+=2*titleBarPad(); QFile in(xdgConfigFolder() + "/qtcurve/" BORDER_SIZE_FILE); int prevSize(-1), prevToolSize(-1), prevSide(-1), prevBot(-1); if(in.open(QIODevice::ReadOnly)) { QTextStream stream(&in); prevSize=in.readLine().toInt(); prevToolSize=in.readLine().toInt(); prevBot=in.readLine().toInt(); prevSide=in.readLine().toInt(); in.close(); } setBorderSize(); int borderEdge=borderEdgeSize()*2; bool borderSizesChanged=prevSize!=(m_titleHeight+borderEdge) || prevToolSize!=(m_titleHeightTool+borderEdge) || prevBot!=borderSize(true) || prevSide!=borderSize(false); if(borderSizesChanged) { KSaveFile sizeFile(xdgConfigFolder() + "/qtcurve/" BORDER_SIZE_FILE); if (sizeFile.open()) { QTextStream stream(&sizeFile); stream << m_titleHeight+borderEdge << endl << m_titleHeightTool+borderEdge << endl << borderSize(true) << endl << borderSize(false) << endl; stream.flush(); sizeFile.finalize(); sizeFile.close(); } } #if KDE_IS_VERSION(4, 3, 0) bool shadowChanged(false); if(customShadows()) { QtCurveShadowConfiguration actShadow(QPalette::Active), inactShadow(QPalette::Inactive); actShadow.load(&configFile); inactShadow.load(&configFile); shadowChanged=m_shadowCache.shadowConfigurationChanged(actShadow) || m_shadowCache.shadowConfigurationChanged(inactShadow); m_shadowCache.setShadowConfiguration(actShadow); m_shadowCache.setShadowConfiguration(inactShadow); if(shadowChanged || oldConfig.roundBottom()!=roundBottom()) m_shadowCache.reset(); } #endif if(m_dBus && (borderSizesChanged || changedBorder)) { m_dBus->emitBorderSizes(); // KDE4 apps... borderSizeChanged(); // Gtk2 apps... } return changedBorder || oldSize!=m_titleHeight || oldToolSize!=m_titleHeightTool || #if KDE_IS_VERSION(4, 3, 0) shadowChanged || #endif m_config!=oldConfig; }
void TestTitle::render(kuto::Graphics2D& g) const { const kuto::Color color(1.f, 1.f, 1.f, 1.f); const kuto::Vector2 windowSize(100.f, 60.f); const kuto::Vector2 windowPosition(160.f - windowSize.x * 0.5f, 180.f - windowSize.y * 0.5f); { kuto::Vector2 pos(screenOffset_); kuto::Texture const& tex = drawTitle_? titleTex_ : gameoverTex_; kuto::Vector2 scale(tex.orgWidth(), tex.orgHeight()); scale *= screenScale_; g.drawTexture(tex, pos, scale, color, true); scale = windowSize; pos = windowPosition; pos *= screenScale_; pos += screenOffset_; scale *= screenScale_; kuto::Vector2 texcoord0(0.f, 0.f); kuto::Vector2 texcoord1(32.f / systemTex_.width(), 32.f / systemTex_.height()); g.drawTexture(systemTex_, pos, scale, color, texcoord0, texcoord1); texcoord0.set(32.f / systemTex_.width(), 0.f); texcoord1.set(64.f / systemTex_.width(), 32.f / systemTex_.height()); kuto::Vector2 borderSize(8.f, 8.f); kuto::Vector2 borderCoord(8.f / systemTex_.width(), 8.f / systemTex_.height()); borderSize *= screenScale_; g.drawTexture9Grid(systemTex_, pos, scale, color, texcoord0, texcoord1, borderSize, borderCoord); scale.set(92.f, 16.f); pos.set(114.f, 154.f + cursor_ * 18.f); pos *= screenScale_; pos += screenOffset_; scale *= screenScale_; if ((animationCounter_ / 6) % 2 == 0) { texcoord0.set(64.f / systemTex_.width(), 0.f); texcoord1.set(96.f / systemTex_.width(), 32.f / systemTex_.height()); } else { texcoord0.set(96.f / systemTex_.width(), 0.f); texcoord1.set(128.f / systemTex_.width(), 32.f / systemTex_.height()); } borderSize *= screenScale_; g.drawTexture9Grid(systemTex_, pos, scale, color, texcoord0, texcoord1, borderSize, borderCoord); } { kuto::Vector2 scale = windowSize; kuto::Vector2 pos = windowPosition; pos *= screenScale_; pos += screenOffset_; scale *= screenScale_; const char* str = rpgLdb_.vocabulary(114).c_str(); // "New Game"; float fontSize = 16.f * screenScale_.x; scale = kuto::Font::instance().textSize(str, fontSize, kuto::Font::NORMAL); pos.x = 160.f * screenScale_.x - scale.x * 0.5f; pos.x += screenOffset_.x; pos.y += 2.f * screenScale_.y; g.drawText(str, pos, color, fontSize, kuto::Font::NORMAL); str = rpgLdb_.vocabulary(115).c_str(); // "Continue"; scale = kuto::Font::instance().textSize(str, fontSize, kuto::Font::NORMAL); pos.x = 160.f * screenScale_.x - scale.x * 0.5f; pos.x += screenOffset_.x; pos.y += fontSize + 2.f * screenScale_.y; g.drawText(str, pos, color, fontSize, kuto::Font::NORMAL); str = rpgLdb_.vocabulary(117).c_str(); // "Shutdown"; scale = kuto::Font::instance().textSize(str, fontSize, kuto::Font::NORMAL); pos.x = 160.f * screenScale_.x - scale.x * 0.5f; pos.x += screenOffset_.x; pos.y += fontSize + 2.f * screenScale_.y; g.drawText(str, pos, color, fontSize, kuto::Font::NORMAL); } }
static bool ipp_Deriv(InputArray _src, OutputArray _dst, int dx, int dy, int ksize, double scale, double delta, int borderType) { #ifdef HAVE_IPP_IW CV_INSTRUMENT_REGION_IPP() ::ipp::IwiSize size(_src.size().width, _src.size().height); IppDataType srcType = ippiGetDataType(_src.depth()); IppDataType dstType = ippiGetDataType(_dst.depth()); int channels = _src.channels(); bool useScale = false; bool useScharr = false; if(channels != _dst.channels() || channels > 1) return false; if(fabs(delta) > FLT_EPSILON || fabs(scale-1) > FLT_EPSILON) useScale = true; if(ksize <= 0) { ksize = 3; useScharr = true; } IppiMaskSize maskSize = ippiGetMaskSize(ksize, ksize); if((int)maskSize < 0) return false; #if IPP_VERSION_X100 <= 201703 // Bug with mirror wrap if(borderType == BORDER_REFLECT_101 && (ksize/2+1 > size.width || ksize/2+1 > size.height)) return false; #endif IwiDerivativeType derivType = ippiGetDerivType(dx, dy, (useScharr)?false:true); if((int)derivType < 0) return false; // Acquire data and begin processing try { Mat src = _src.getMat(); Mat dst = _dst.getMat(); ::ipp::IwiImage iwSrc = ippiGetImage(src); ::ipp::IwiImage iwDst = ippiGetImage(dst); ::ipp::IwiImage iwSrcProc = iwSrc; ::ipp::IwiImage iwDstProc = iwDst; ::ipp::IwiBorderSize borderSize(maskSize); ::ipp::IwiBorderType ippBorder(ippiGetBorder(iwSrc, borderType, borderSize)); if(!ippBorder) return false; if(srcType == ipp8u && dstType == ipp8u) { iwDstProc.Alloc(iwDst.m_size, ipp16s, channels); useScale = true; } else if(srcType == ipp8u && dstType == ipp32f) { iwSrc -= borderSize; iwSrcProc.Alloc(iwSrc.m_size, ipp32f, channels); CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, iwSrc, iwSrcProc, 1, 0, ::ipp::IwiScaleParams(ippAlgHintFast)); iwSrcProc += borderSize; } if(useScharr) CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterScharr, iwSrcProc, iwDstProc, derivType, maskSize, ::ipp::IwDefault(), ippBorder); else CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterSobel, iwSrcProc, iwDstProc, derivType, maskSize, ::ipp::IwDefault(), ippBorder); if(useScale) CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, iwDstProc, iwDst, scale, delta, ::ipp::IwiScaleParams(ippAlgHintFast)); } catch (::ipp::IwException) { return false; } return true; #else CV_UNUSED(_src); CV_UNUSED(_dst); CV_UNUSED(dx); CV_UNUSED(dy); CV_UNUSED(ksize); CV_UNUSED(scale); CV_UNUSED(delta); CV_UNUSED(borderType); return false; #endif }
void BoxLayout::updateLayout(const MFUnrecComponentPtr* Components, const Component* ParentComponent) const { /*! totalMajorAxis will be the sum of the MajorAxis of all of the components, which is compared to MajorAxis, which is MajorAxis of the parent component. These two variables will be used to determine the spacing of each of the objects. */ UInt32 AxisIndex(0); if(getOrientation() != HORIZONTAL_ORIENTATION ) AxisIndex = 1; Pnt2f borderTopLeft, borderBottomRight; dynamic_cast<const ComponentContainer*>(ParentComponent)->getInsideInsetsBounds(borderTopLeft, borderBottomRight); Vec2f borderSize(borderBottomRight-borderTopLeft); Real32 MajorAxis(borderSize[AxisIndex]); Real32 totalMajorAxis(0); Real32 largestMinorAxis(0); Real32 spacing(0); Vec2f size; Vec2f offset(0,0); /*! This first sweep through the components sets each component to its preferred size, gets a sum of all the MajorAxes, and finds the largest height. */ for(UInt32 i=0 ; i<Components->size() ; ++i) { // set the component to its preferred size // get sum of all components totalMajorAxis += (*Components)[i]->getPreferredSize()[AxisIndex]; if ((*Components)[i]->getPreferredSize()[(AxisIndex+1)%2] > largestMinorAxis) largestMinorAxis = (*Components)[i]->getPreferredSize()[(AxisIndex+1)%2]; } if(MajorAxis > totalMajorAxis) { spacing = (MajorAxis-totalMajorAxis)/(Components->size()+1); // in the case where there isn't equal spacing between each button, // translate more the first time to center the components if(spacing < getMajorAxisMinimumGap()) { spacing = getMajorAxisMinimumGap(); } if(spacing > getMajorAxisMaximumGap()) { spacing = getMajorAxisMaximumGap(); } borderTopLeft[AxisIndex] += (MajorAxis - (spacing*(Components->size()+1)+totalMajorAxis))*getMajorAxisAlignment() + spacing; } else { spacing = getMajorAxisMinimumGap(); } if(getOrientation() == HORIZONTAL_ORIENTATION) { borderTopLeft = calculateAlignment(borderTopLeft, borderSize, Vec2f(0.0f,largestMinorAxis), getMinorAxisAlignment(), 0.0f); } else { borderTopLeft = calculateAlignment(borderTopLeft, borderSize, Vec2f(largestMinorAxis,0.0f), 0.0f, getMinorAxisAlignment()); } /*! This second sweep through the components sets each component to the matching highest height, then positions each component equally spaced apart */ for(UInt32 i=0; i<Components->size(); ++i) { // for each individual button, keep track of the offsetMinorAxis in height // for use in keeping them vertically centered offset[(AxisIndex+1)%2] = 0; // change the component's height only if necessary if (largestMinorAxis > (*Components)[i]->getPreferredSize()[(AxisIndex+1)%2]) { if (largestMinorAxis <= (*Components)[i]->getMaxSize()[(AxisIndex+1)%2]) { // for when the max height is larger than the largestMinorAxis size[AxisIndex] = (*Components)[i]->getPreferredSize()[AxisIndex]; size[(AxisIndex+1)%2] = largestMinorAxis; } else { // in this case, max out the button to its max height size[AxisIndex] = (*Components)[i]->getPreferredSize()[AxisIndex]; size[(AxisIndex+1)%2] = (*Components)[i]->getMaxSize()[(AxisIndex+1)%2]; // find how far to set offset to make this button properly aligned if(getOrientation() == HORIZONTAL_ORIENTATION) { offset = Vec2f(calculateAlignment(Pnt2f(0,0), Vec2f(0.0f, largestMinorAxis), Vec2f(0.0f,(*Components)[i]->getMaxSize().y()), getComponentAlignment(), 0.0f)); } else { offset = Vec2f(calculateAlignment(Pnt2f(0,0), Vec2f(largestMinorAxis,0.0f), Vec2f((*Components)[i]->getMaxSize().x(),0.0f), 0.0f, getComponentAlignment())); } } } else { size = (*Components)[i]->getPreferredSize(); } (*Components)[i]->setSize(size); (*Components)[i]->setPosition(borderTopLeft + offset); // now set offset for the next button offset[AxisIndex] += spacing + (*Components)[i]->getPreferredSize()[AxisIndex]; } }
void GridLayout::updateLayout(const MFUnrecChildComponentPtr* Components, const Component* ParentComponent) const { Pnt2f borderTopLeft, borderBottomRight; dynamic_cast<const ComponentContainer*>(ParentComponent)->getInsideInsetsBounds(borderTopLeft, borderBottomRight); Vec2f borderSize(borderBottomRight-borderTopLeft); Real32 Xpos = 0; Real32 Ypos = 0; Real32 maxSizeX = (borderSize.x()-getHorizontalGap()*(getColumns()-1)) / static_cast<Real32>(getColumns()); Real32 maxSizeY = 0.0f;//(borderSize.y()-getVerticalGap()*getRows()) / static_cast<Real32>(getRows()); Int32 numComp = Components->size(); Real32 buttonXSize, buttonYSize; //set the size to the perfered sizes for(UInt16 i = 0; i<Components->size(); i++) { if ((*Components)[i] != NULL) { if((*Components)[i]->getPreferredSize().x()>maxSizeX) maxSizeX = (*Components)[i]->getPreferredSize().x(); if((*Components)[i]->getPreferredSize().y()>maxSizeY) maxSizeY = (*Components)[i]->getPreferredSize().y(); } } //set the size of the button for(UInt16 i = 0; i < Components->size(); i++) { if ((*Components)[i] != NULL) { if(maxSizeX < (*Components)[i]->getMaxSize().x()) { buttonXSize = maxSizeX; } else buttonXSize = (*Components)[i]->getMaxSize().x(); if(maxSizeY<(*Components)[i]->getMaxSize().y()) { buttonYSize = maxSizeY; } else { buttonYSize = (*Components)[i]->getMaxSize().y(); } if((*Components)[i]->getSize() != Vec2f(buttonXSize, buttonYSize)) { (*Components)[i]->setSize(Vec2f(buttonXSize, buttonYSize)); } } } //position each component for(UInt16 i = 0; i < osgMin(getRows(), numComp/getColumns()); i++) { if ((*Components)[i] != NULL) { Pnt2f Pos; for(UInt16 j = 0; j < osgMin(getColumns(),numComp - i*getColumns()) ; j++) { Pos = borderTopLeft + Vec2f(Xpos, Ypos); if((*Components)[i*getColumns()+j]->getPosition() != Pos) { (*Components)[i*getColumns()+j]->setPosition(Pos); } Xpos = Xpos + (maxSizeX+getHorizontalGap()); } Xpos = 0; Ypos += maxSizeY+getVerticalGap(); } } }
void AbsoluteLayout::updateLayout(const MFUnrecChildComponentPtr* Components, const Component* ParentComponent) const { Pnt2f ParentInsetsTopLeft, ParentInsetBottomRight; dynamic_cast<const ComponentContainer*>(ParentComponent)->getInsideInsetsBounds(ParentInsetsTopLeft, ParentInsetBottomRight); Vec2f borderSize(ParentInsetBottomRight-ParentInsetsTopLeft); Vec2f ComponentSize; Pnt2f ComponentPosition; for(UInt32 i = 0 ; i<Components->size(); ++i) { //Calculate the Components Size if((*Components)[i]->getConstraints() != NULL) { ComponentPosition = dynamic_cast<AbsoluteLayoutConstraints*>((*Components)[i]->getConstraints())->getPosition(); } else { ComponentPosition.setValues(0.0f,0.0f); } ComponentSize = (*Components)[i]->getPreferredSize(); if(getScaling()) { Vec2f DifferenceRatio(borderSize.x() / getOriginalDimensions().x(), borderSize.y() / getOriginalDimensions().y()); ComponentPosition.setValues(ComponentPosition.x() * DifferenceRatio.x(), ComponentPosition.y() * DifferenceRatio.y()); ComponentSize.setValues(ComponentSize.x() * DifferenceRatio.x(), ComponentSize.y() * DifferenceRatio.y()); } else { if(ComponentPosition.x() <= 1.0f) { ComponentPosition[0] = ComponentPosition.x() * borderSize.x(); } if(ComponentPosition.y() <= 1.0f) { ComponentPosition[1] = ComponentPosition.y() * borderSize.y(); } if(ComponentSize.x() <= 1.0f) { ComponentSize[0] = ComponentSize.x() * borderSize.x(); } if(ComponentSize.y() <= 1.0f) { ComponentSize[1] = ComponentSize.y() * borderSize.y(); } } ComponentPosition = ParentInsetsTopLeft + ComponentPosition.subZero(); if((*Components)[i]->getPosition() != ComponentPosition) { (*Components)[i]->setPosition(ComponentPosition); } if((*Components)[i]->getSize() != ComponentSize) { (*Components)[i]->setSize(ComponentSize); } } }
Size Grid::Measure(const Size availableSize) { RebuildCellDataIfNeeded(); Size borderSize(GetBorderAndPaddingSize(cachedStyle)); Cell* cell; Control* el; for (Grid::CellData& d : els) { cell = GetCell(d.row, d.col); cell->desiredSize.Width = 0; cell->desiredSize.Height = 0; el = d.el; if (!el->IsVisible()) continue; // calculate max dx of each column (dx of widest cell in the row) // and max dy of each row (dy of tallest cell in the column) el->Measure(availableSize); // TODO: take cell's border and padding into account cell->desiredSize = el->DesiredSize(); // if a cell spans multiple columns, we don't count its size here if (d.colSpan == 1) { if (cell->desiredSize.Width > maxColWidth[d.col]) maxColWidth[d.col] = cell->desiredSize.Width; } if (cell->desiredSize.Height > maxRowHeight[d.row]) maxRowHeight[d.row] = cell->desiredSize.Height; } // account for cells with colSpan > 1. If cell.dx > total dx // of columns it spans, we widen the columns by equally // re-distributing the difference among columns for (Grid::CellData& d : els) { if (d.colSpan == 1) continue; cell = GetCell(d.row, d.col); int totalDx = 0; for (int i = d.col; i < d.col + d.colSpan; i++) { totalDx += maxColWidth[i]; } int diff = cell->desiredSize.Width - totalDx; if (diff > 0) { int diffPerCol = diff / d.colSpan; int rest = diff % d.colSpan; // note: we could try to redistribute rest for ideal sizing instead of // over-sizing but not sure if that would matter in practice if (rest > 0) diffPerCol += 1; CrashIf(diffPerCol * d.colSpan < diff); for (int i = d.col; i < d.col + d.colSpan; i++) { maxColWidth[i] += diffPerCol; } } } int desiredWidth = 0; int desiredHeight = 0; for (int row = 0; row < rows; row++) { desiredHeight += maxRowHeight[row]; } for (int col = 0; col < cols; col++) { desiredWidth += maxColWidth[col]; } // TODO: what to do if desired size is more than availableSize? desiredSize.Width = desiredWidth + borderSize.Width; desiredSize.Height = desiredHeight + borderSize.Height; return desiredSize; }
void OptionSelectionMenu::Render(RenderDevice* prender, String title) { // If we are invisible, render shortcut notifications. // Both child and parent have visible == true even if only child is shown. if (DisplayState == Display_None) { renderShortcutChangeMessage(prender); return; } title += Label; // Delegate to sub-menu if active. if (GetSubmenu() != NULL) { if (title.GetSize() > 0) title += " > "; GetSubmenu()->Render(prender, title); return; } Color focusColor(180, 80, 20, 210); Color pickedColor(120, 55, 10, 140); Color titleColor(0x18, 0x1A, 0x4D, 210); Color titleOutlineColor(0x18, 0x18, 0x18, 240); float labelsSize[2] = {0.0f, 0.0f}; float bufferSize[2] = {0.0f, 0.0f}; float valuesSize[2] = {0.0f, 0.0f}; float maxValueWidth = 0.0f; UPInt selection[2] = { 0, 0 }; Vector2f labelSelectionRect[2]; Vector2f valueSelectionRect[2]; bool havelLabelSelection = false; bool haveValueSelection = false; float textSize = 22.0f; prender->MeasureText(&DejaVu, " ", textSize, bufferSize); String values; String menuItems; int highlightIndex = 0; if (DisplayState == Display_Menu) { highlightIndex = SelectedIndex; for (UInt32 i = 0; i < Items.GetSize(); i++) { if (i > 0) values += "\n"; values += Items[i]->GetValue(); } for (UInt32 i = 0; i < Items.GetSize(); i++) { if (i > 0) menuItems += "\n"; menuItems += Items[i]->GetLabel(); } } else { values = Items[SelectedIndex]->GetValue(); menuItems = Items[SelectedIndex]->GetLabel(); } // Measure labels const char* menuItemsCStr = menuItems.ToCStr(); havelLabelSelection = FindLineCharRange(menuItemsCStr, highlightIndex, selection); prender->MeasureText(&DejaVu, menuItemsCStr, textSize, labelsSize, selection, labelSelectionRect); // Measure label-to-value gap const char* valuesCStr = values.ToCStr(); haveValueSelection = FindLineCharRange(valuesCStr, highlightIndex, selection); prender->MeasureText(&DejaVu, valuesCStr, textSize, valuesSize, selection, valueSelectionRect); // Measure max value size (absolute size varies, so just use a reasonable max) maxValueWidth = prender->MeasureText(&DejaVu, "Max value width", textSize); maxValueWidth = Alg::Max(maxValueWidth, valuesSize[0]); Vector2f borderSize(4.0f, 4.0f); Vector2f totalDimensions = borderSize * 2 + Vector2f(bufferSize[0], 0) + Vector2f(maxValueWidth, 0) + Vector2f(labelsSize[0], labelsSize[1]); Vector2f fudgeOffset= Vector2f(10.0f, 25.0f); // This offset looks better Vector2f topLeft = (-totalDimensions / 2.0f) + fudgeOffset; Vector2f bottomRight = topLeft + totalDimensions; // If displaying a single item, shift it down. if (DisplayState == Display_SingleItem) { topLeft.y += textSize * 7; bottomRight.y += textSize * 7; } prender->FillRect(topLeft.x, topLeft.y, bottomRight.x, bottomRight.y, Color(40,40,100,210)); Vector2f labelsPos = topLeft + borderSize; Vector2f valuesPos = labelsPos + Vector2f(labelsSize[0], 0) + Vector2f(bufferSize[0], 0); // Highlight selected label Vector2f selectionInset = Vector2f(0.3f, 2.0f); if (DisplayState == Display_Menu) { Vector2f labelSelectionTopLeft = labelsPos + labelSelectionRect[0] - selectionInset; Vector2f labelSelectionBottomRight = labelsPos + labelSelectionRect[1] + selectionInset; prender->FillRect(labelSelectionTopLeft.x, labelSelectionTopLeft.y, labelSelectionBottomRight.x, labelSelectionBottomRight.y, SelectionActive ? pickedColor : focusColor); } // Highlight selected value if active if (SelectionActive) { Vector2f valueSelectionTopLeft = valuesPos + valueSelectionRect[0] - selectionInset; Vector2f valueSelectionBottomRight = valuesPos + valueSelectionRect[1] + selectionInset; prender->FillRect(valueSelectionTopLeft.x, valueSelectionTopLeft.y, valueSelectionBottomRight.x, valueSelectionBottomRight.y, focusColor); } // Measure and draw title if (DisplayState == Display_Menu && title.GetLength() > 0) { Vector2f titleDimensions; prender->MeasureText(&DejaVu, title.ToCStr(), textSize, &titleDimensions.x); Vector2f titleTopLeft = topLeft - Vector2f(0, borderSize.y) * 2 - Vector2f(0, titleDimensions.y); titleDimensions.x = totalDimensions.x; prender->FillRect(titleTopLeft.x, titleTopLeft.y, titleTopLeft.x + totalDimensions.x, titleTopLeft.y + titleDimensions.y + borderSize.y * 2, titleOutlineColor); prender->FillRect(titleTopLeft.x + borderSize.x / 2, titleTopLeft.y + borderSize.y / 2, titleTopLeft.x + totalDimensions.x - borderSize.x / 2, titleTopLeft.y + borderSize.y / 2 + titleDimensions.y, titleColor); prender->RenderText(&DejaVu, title.ToCStr(), titleTopLeft.x + borderSize.x, titleTopLeft.y + borderSize.y, textSize, Color(255,255,0,210)); } prender->RenderText(&DejaVu, menuItemsCStr, labelsPos.x, labelsPos.y, textSize, Color(255,255,0,210)); prender->RenderText(&DejaVu, valuesCStr, valuesPos.x, valuesPos.y, textSize, Color(255,255,0,210)); }