⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 etslayout.cpp

📁 PC抄表软件, 用于降数据上载到PC机上, 通过USB传COM口实现.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		CPaneBase pItem = m_paneItems[i];

		if( m_Orientation == HORIZONTAL ) {

			// for absolute items subtract their size from available space
			if(pItem->modeResize() & ABSOLUTE_HORZ) {
				availSpace -= (sizePrimary[i] = pItem->getConstrainHorz(0));
			}

			// count Greedy items for later
			if(!(pItem->modeResize() & ABSOLUTE_HORZ) && !(pItem->modeResize() & RELATIVE_HORZ)) {
				nGreedy++;
			}

			sizeMin[i] = pItem->getMinConstrainHorz();
			sizeMax[i] = pItem->getMaxConstrainHorz();
		}
		else {

			// for absolute items subtract their size from available space
			if(pItem->modeResize() & ABSOLUTE_VERT) {
				availSpace -= (sizePrimary[i] = pItem->getConstrainVert(0));
			}

			// count Greedy items for later
			if(!(pItem->modeResize() & ABSOLUTE_VERT) && !(pItem->modeResize() & RELATIVE_VERT)) {
				nGreedy++;
			}

			sizeMin[i] = pItem->getMinConstrainVert();
			sizeMax[i] = pItem->getMaxConstrainVert();
		}

	}

	// Must not be negative !!
	availSpace = max(availSpace, 0);

	return nGreedy;
}

bool ETSLayoutMgr::Pane::resizeToRelative(int& availSpace, CArray<int,int>& sizePrimary,
										 CArray<int,int>& sizeMin, CArray<int,int>& sizeMax)
{
	// Then all relative items as percentage of left space (as of now after
	// all absolute items are subtracted

	int availRel = availSpace;	// At the beginning all of remaining space is available. We want all
								// operation to be relative to the left space at this moment, so we
								// save this amount here. Then we safly can lower availSpace

	int relDiff = 0;			// The cumulated difference between first proposed size and
								// eventual maximum/minimum size. This amount has to be
								// saved in some other place (i.e. where relativ items/subpane
								// are not limited by min/max
	
	int relLeft = 0;			// The cumulated amout of space that can be saved by
								// shrinking the items/panes up to the minimum
	
	int relCount = 0;			// Actually allocated item/subpane's cumulated primary sizes 
								// of non-limited items/subpanes (these can be modified in fixup)
								// needed for equally distribution of differences amoung non-limited
								// relative items/subpanes

	for(int i=0; i<m_paneItems.GetSize(); ++i) {
		CPaneBase pItem = m_paneItems[i];

		// For all relative items in primary direction
		if( (m_Orientation==HORIZONTAL && pItem->modeResize() & RELATIVE_HORZ)
			||
			(m_Orientation==VERTICAL   && pItem->modeResize() & RELATIVE_VERT) )
		{
			// minimum item/subpane size in primary direction (pixels)
			int nSizeRelMin = sizeMin[i];

			// maximum item/subpane size in primary direction (pixels)
			int nSizeRelMax = sizeMax[i];

			// Relative size in primary direction (pixels)
			int nSizeRel	= (m_Orientation==HORIZONTAL) 
									? 
									(pItem->getConstrainHorz(availRel)) 
									:
									(pItem->getConstrainVert(availRel));

			if( nSizeRel < nSizeRelMin) {
				// The item/pane is shrinked too small!
				// We will grow it to it's minimum-size. In order not to modify
				// this item later when fixing up set the size to the negative
				// minimum size
				sizePrimary[i]	= -nSizeRelMin;

				// As we grew one item/subpane we have to shrink another one.
				// We keep count on how much space we needed to grow the item
				// to it's minimum size
				relDiff += ( nSizeRelMin - nSizeRel );
			}
			else if(  nSizeRelMax != -1 && nSizeRel > nSizeRelMax) {
				// if there's a maximum size (nSizeRelMax != -1) and our item/subpane
				// is to be resized over that amount correct it.  In order not to modify
				// this item later when fixing up set the size to the negative
				// maximum size
				sizePrimary[i]	= -nSizeRelMax;

				// As we shrinked one item/subpane we have to grow another one.
				// We keep count on how much space we needed to grow the item
				// to it's maximum size.
				relDiff += ( nSizeRelMax - nSizeRel );
			}
			else {
				// this is the normal case: neither are we minimum limited nor maximum
				// limited

				// As this item/subpane is larger that it's minimum we could later (if
				// necessary for fixup) shrink it for the difference amount of pixels
				relLeft	+= ( nSizeRel - nSizeRelMin );

				// Set the primary size of this item/pane. Can later be modified by fixup
				sizePrimary[i]	= nSizeRel;

				// Add this item/subpane's primary size to the count of already allocated
				// cumulated size of non-limited items/subpanes (these can be modified in fixup)
				relCount	+= nSizeRel;
			}

			// decrease available space by used space in this step
			availSpace	-= nSizeRel;
		}
	}

	// We now have the situation that some items/subpanes had to be adjusted for cumulated
	// relDiff pixels (positive value means more space taken than indicated by percentage of
	// left space). On the other hand we have some items/subpanes which were not limited (in 
	// their current dimensions) but could be if necessary up to relLeft pixels. 
	if(relLeft < relDiff && availSpace >= (relDiff-relLeft) ){		

		// If it's not possible to shrink other (relative) panes in order to distribute the
		// difference because the left for shrinking (relLeft) is too small we need to aquire
		// more space from the globally left space (if available at all)
		availSpace -= (relDiff-relLeft);
		relDiff = relLeft;
	}

	// At this point we should have some space left (at least not be negative with the leftover
	// space) and on the other hand there's enough space for the limit-difference to be distributed
	ASSERT( availSpace >= 0 && relLeft >= relDiff);

	// Fixup Relative:
	// Distribute (if anecessary) relDiff on other (not limited) relative items/subpanes 
	// (if available - if not later just grow the limited panes)
	while( relDiff != 0 && relCount >= 0 ) {

		// in every iteration there must be some space distributed (of the difference) or it could 
		// come to endless looping. Save the amount of space actually distributed in this iteration
		int relDist = 0;

		for(i=0; i<m_paneItems.GetSize(); ++i) {
			
			CPaneBase pItem = m_paneItems[i];


			// For all relative items in primary direction which were NOT limited
			if( (m_Orientation==HORIZONTAL && (pItem->modeResize() & RELATIVE_HORZ) && sizePrimary[i] > 0)
				||
				(m_Orientation==VERTICAL   && (pItem->modeResize() & RELATIVE_VERT) && sizePrimary[i] > 0) )
			{
				// keep a flag for termination of this iteration
				bool bLast = false;

				// the difference should be distributed amoung all non-limited items/subpanes equally.
				// nDiff is the amount for the current item/subpane
				int nDiff = (relDiff * sizePrimary[i]) / relCount;

				// if it's a too small value just add it to the current pane and break iteration
				if( abs(relDiff) <= FIXUP_CUTOFF ) {
					// take it all in this step
					nDiff = relDiff;

					// set break flag
					bLast = true;
				}

				// calculate the new size for the current item/subpane
				int nNewSize = sizePrimary[i] - nDiff;
			
				if( nNewSize < sizeMin[i] ) {
					// oh, we are limited here. Revise our plan:

					// Not all of the space could be saved, add the actually possible space
					// to the sum
					relDist += ( sizePrimary[i] - sizeMin[i] );

					// set it to the minimum possible size
					sizePrimary[i] = -sizeMin[i];

					// as this item/subpane is now limited it's occupied space doesn't count
					// for relCount anymore
					relCount-= ( sizePrimary[i] );
				}
				else {
					// account the difference of the sizes in relDist and set new size
					relDist += ( sizePrimary[i] - nNewSize );
					sizePrimary[i] = nNewSize;

					// if it's the last one break now
					if(bLast)
						break;
				}
			}
		}
		// Distributed some relDiff-space in every iteration
		ASSERT(relDist != 0);	
		relDiff -= relDist;
	}

	// Fixup Relative: invert all negative (limited) sized to correct value
	for(i=0; i<m_paneItems.GetSize(); ++i) {
		CPaneBase pItem = m_paneItems[i];
		if( (m_Orientation==HORIZONTAL && (pItem->modeResize() & RELATIVE_HORZ) && sizePrimary[i] < 0)
			||
			(m_Orientation==VERTICAL   && (pItem->modeResize() & RELATIVE_VERT) && sizePrimary[i] < 0) )
		{
			sizePrimary[i] *= -1;
		}
	}

	return true;
}

bool ETSLayoutMgr::Pane::resizeToGreedy(int& availSpace, int nGreedy, CArray<int,int>& sizePrimary, 
									   CArray<int,int>& sizeMin, CArray<int,int>& sizeMax)
{
	// Now resize all Greedy items/subpanes equally among the remaining space
	int greedyDiff = 0;			// The cumulated difference between first proposed size and
								// eventual maximum/minimum size. This amount has to be
								// saved in some other place (i.e. where items/subpane
								// are not limited by min/max
	
	int greedyLeft = 0;			// The cumulated amount of space that can be saved by
								// shrinking the items/panes up to the minimum
	
	int greedyCount = 0;		// Actually allocated item/subpane's cumulated primary sizes 
								// of non-limited items/subpanes (these can be modified in fixup)
								// needed for equally distribution of differences amoung non-limited
								// items/subpanes

	for(int i=0; i<m_paneItems.GetSize(); ++i) {
		CPaneBase pItem = m_paneItems[i];


		if( (m_Orientation==HORIZONTAL 
				&& !(pItem->modeResize()&ABSOLUTE_HORZ) 
				&& !(pItem->modeResize()&RELATIVE_HORZ)
			)
			||
			(m_Orientation==VERTICAL   
				&& !(pItem->modeResize()&ABSOLUTE_VERT) 
				&& !(pItem->modeResize()&RELATIVE_VERT)
			) 
		)
		{

			// All greedy items get an equal portion of the left space
			int nSize		= availSpace / nGreedy;

			// minimum item/subpane size in primary direction (pixels)
			int nSizeMin	= sizeMin[i];

			// maximum item/subpane size in primary direction (pixels)
			int nSizeMax	= sizeMax[i];


			// the last gets the all of the remaining space
			if( nGreedy == 1 )
				nSize = availSpace;						

			if( nSize < nSizeMin) {
				// The item/pane is shrinked too small!
				// We will grow it to it's minimum-size. In order not to modify
				// this item later when fixing up set the size to the negative
				// minimum size
				sizePrimary[i]	= -nSizeMin;

				// As we grew one item/subpane we have to shrink another one.
				// We keep count on how much space we needed to grow the item
				// to it's minimum size
				greedyDiff		+= ( nSizeMin - nSize );
			}
			else if( nSizeMax != -1 && nSize > nSizeMax) {
				// if there's a maximum size (nSizeRelMax != -1) and our item/subpane
				// is to be resized over that amount correct it.  In order not to modify
				// this item later when fixing up set the size to the negative
				// maximum size
				sizePrimary[i]	= -nSizeMax;

				// As we shrinked one item/subpane we have to grow another one.
				// We keep count on how much space we needed to grow the item
				// to it's maximum size.
				greedyDiff		+= ( nSizeMax - nSize );
			}
			else {

				// this is the normal case: neither are we minimum limited nor maximum
				// limited

				// As this item/subpane is larger that it's minimum we could later (if
				// necessary for fixup) shrink it for the difference amount of pixels
				greedyLeft		+= ( nSize - nSizeMin );

				// Set the primary size of this item/pane. Can later be modified by fixup
				sizePrimary[i]	= nSize;

				// Add this item/subpane's primary size to the count of already allocated
				// cumulated size of non-limited items/subpanes (these can be modified in fixup)
				greedyCount		+= nSize;
			}

			// decrease available space by used space in this step
			availSpace	-= nSize;

			// one greedy item/subpane complete
			--nGreedy;
		}
	}


	// Fixup Greedy I
	// Distribute (if anecessary) greedyDiff on other (not limited) greedy items/subpanes 
	// (if available - if not later just grow the limited panes)

	// at least on not limited item present
	bool bAtLeastOne = true;

	while( bAtLeastOne && greedyDiff != 0 && greedyCount > 0) {

		// in every iteration there must be some space distributed (of the difference) or it could 
		// come to endless looping. Save the amount of space actually distributed in this iteration
		int greedyDist = 0;

		// at least on not limited item present
		bAtLeastOne = false;

		for(i=0; i<m_paneItems.GetSize(); ++i) {
			CPaneBase pItem = m_paneItems[i];


			if( (m_Orientation==HORIZONTAL 
					&& !(pItem->modeResize()&ABSOLUTE_HORZ) 
					&& !(pItem->modeResize()&RELATIVE_HORZ)
					&& sizePrimary[i] > 0
				)	
				||
				(m_Orientation==VERTICAL   
					&& !(pItem->modeResize()&ABSOLUTE_VERT) 
					&& !(pItem->modeResize()&RELATIVE_VERT)
					&& sizePrimary[i] > 0 
				)
			)
			{
	 			// keep a flag for termination of this iteration
				bool bLast = false;

				// the difference should be distributed amoung all non-limited items/subpanes equally.
				// nDiff is the amount for the current item/subpane
				int nDiff = (greedyDiff * sizePrimary[i]) / greedyCount;

				// if it's a too small value just add it to the current pane and break iteration
				if( abs(greedyDiff) <= FIXUP_CUTOFF || nDiff == 0) {
					// take it all in this step
					nDiff = greedyDiff;

					// set break flag
					bLast = true;
				}

				// calculate the new size for the current item/subpane
				int nNewSize = sizePrimary[i] - nDiff;
			
				if( nNewSize < sizeMin[i] ) {
					// oh, we are limited here. Revise our plan:

					if( sizePrimary[i] != sizeMin[i] )
						bAtLeastOne = true;

					// Not all of the space could be saved, add the actually possible space
					// to the sum
					greedyDist += ( sizePrimary[i] - sizeMin[i] );

					// set it to the minimum possible size
					sizePrimary[i] = sizeMin[i];

					// as this item/subpane is now limited it's occupied space doesn't count
					// for relCount anymore
					greedyCount -= ( sizePrimary[i] );
				}
				else {
					// yes, there is one
					bAtLeastOne = true;

					// account the difference of the sizes in relDist and set new size
					greedyDist += ( sizePrimary[i] - nNewSize );
					sizePrimary[i] = nNewSize;

					// if it's the last one break now
					if(bLast)
						break;
				}
			}
		}
		// Distributed some greedyDiff-space in every iteration
		ASSERT(!bAtLeastOne || greedyDist != 0 || greedyCount<=0);
		greedyDiff -= greedyDist;
	}


	// Fixup Greedy II
	if( greedyDiff < 0 ) {
		// still difference, some space left

		// are there any items which are minimum-limited where we can give more space?
		for(i=0; i<m_paneItems.GetSize() && greedyDiff!=0; ++i) {
			CPaneBase pItem = m_paneItems[i];

			if( (m_Orientation==HORIZONTAL 
					&& !(pItem->modeResize()&ABSOLUTE_HORZ) 
					&& !(pItem->modeResize()&RELATIVE_HORZ)
				)	
				||
				(m_Orientation==VERTICAL   
					&& !(pItem->modeResize()&ABSOLUTE_VERT) 
					&& !(pItem->modeResize()&RELATIVE_VERT)
				)
			)
			{
				if( sizePrimary[i] == -sizeMin[i] ) {
					// fill this one up as much as possible
					if( sizeMax[i] == -1) {
						// all fits in
						sizePrimary[i] += greedyDiff;
						greedyDiff = 0;
					}
					else {
						sizePrimary[i] += -min( -greedyDiff, sizeMax[i]-sizeMin[i]);
						greedyDiff     -= -min( -greedyDiff, sizeMax[i]-sizeMin[i]);
					}
				}
			}
		}
	}


	// Fixup Greedy III: invert all negative (limited) sized to correct value
	for(i=0; i<m_paneItems.GetSize(); ++i) {
		CPaneBase pItem = m_paneItems[i];

		if( (m_Orientation==HORIZONTAL 
				&& !(pItem->modeResize() & ABSOLUTE_HORZ) 
				&& !(pItem->modeResize() & RELATIVE_HORZ) 
				&& sizePrimary[i] < 0
			)
			||
			(m_Orientation==VERTICAL   
				&& !(pItem->modeResize() & ABSOLUTE_VERT) 
				&& !(pItem->modeResize() & RELATIVE_VERT) 
				&& sizePrimary[i] < 0
			) 
		)
		{
			if(sizePrimary[i] < 0)
				sizePrimary[i] *= -1;
		}
	}

	return true;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -