void CTreePropSheetSplitter::SetPaneHeight(int nIndex,int nHeight) { ASSERT(nIndex >= 0 && nIndex < m_nPanes); if (m_nOrientation == SSP_VERT) { m_orig[nIndex + 1] = nHeight + m_nBarThickness ; CRect rcClient; int mouse_pos = nHeight; for (m_nTrackIndex = 1; (m_nTrackIndex < m_nPanes && m_orig[m_nTrackIndex] < mouse_pos); m_nTrackIndex++); m_nTracker = m_orig[m_nTrackIndex]; m_nTrackerMouseOffset = mouse_pos - m_nTracker; GetWindowRect(&rcClient); GetParent()->ScreenToClient(&rcClient); m_nTrackerLength = rcClient.Width(); CRect rcOuter; int size_sum; GetAdjustedClientRect(&rcOuter); size_sum = m_nOrientation == SSP_HORZ ? rcOuter.Width() : rcOuter.Height(); size_sum -= (m_nPanes - 1) * m_nBarThickness; m_orig[m_nTrackIndex] = m_nTracker; m_size[m_nTrackIndex - 1] = MulDivRound(m_orig[m_nTrackIndex] - m_orig[m_nTrackIndex - 1] - m_nBarThickness, FULL_SIZE, size_sum); m_size[m_nTrackIndex] = MulDivRound(m_orig[m_nTrackIndex + 1] - m_orig[m_nTrackIndex] - m_nBarThickness, FULL_SIZE, size_sum); ResizePanes(); } }
void CTreePropSheetSplitter::OnLButtonUp(UINT nFlags, CPoint point) { UNREFERENCED_PARAMETER(nFlags); UNREFERENCED_PARAMETER(point); if (GetCapture() != this) return; CRect rcOuter; int size_sum; GetAdjustedClientRect(&rcOuter); size_sum = m_nOrientation == SSP_HORZ ? rcOuter.Width() : rcOuter.Height(); size_sum -= (m_nPanes - 1) * m_nBarThickness; InvertTracker(); ReleaseCapture(); m_orig[m_nTrackIndex] = m_nTracker; m_size[m_nTrackIndex - 1] = MulDivRound(m_orig[m_nTrackIndex] - m_orig[m_nTrackIndex - 1] - m_nBarThickness, FULL_SIZE, size_sum); m_size[m_nTrackIndex] = MulDivRound(m_orig[m_nTrackIndex + 1] - m_orig[m_nTrackIndex] - m_nBarThickness, FULL_SIZE, size_sum); ResizePanes(); }
void CTreePropSheetSplitter::SetPaneSizes(const int* sizes) { int i, total = 0, total_in = 0; for (i = 0; i < m_nPanes; i++) { ASSERT(sizes[i] >= 0); total += sizes[i]; } for (i = 0; i < m_nPanes - 1; i++) { m_size[i] = MulDivRound(sizes[i], FULL_SIZE, total); total_in += m_size[i]; } m_size[m_nPanes - 1] = FULL_SIZE - total_in; RecalcLayout(); ResizePanes(); }
void CTreePropSheetSplitter::RecalcLayout() { int i, size_sum, remain, remain_new = 0; bool bGrow = true; CRect rcOuter; GetAdjustedClientRect(&rcOuter); size_sum = m_nOrientation == SSP_HORZ ? rcOuter.Width() : rcOuter.Height(); size_sum -= (m_nPanes - 1) * m_nBarThickness; // Frozen panes /* Get the previous size and adjust the size of the frozen pane. We need to do this as the size array contains ratio to FULL_SIZE. */ // If we have some frozen columns use this algorithm otherwise adjust for minimum sizes. // If all the panes are frozen, do not use frozen pane algorithm. bool bFrozenOnly = m_nFrozenPaneCount && m_nPanes - m_nFrozenPaneCount; if( bFrozenOnly ) { int prev_size_sum = m_orig[m_nPanes] - m_orig[0] - m_nBarThickness * m_nPanes; int non_frozen_count = m_nPanes - m_nFrozenPaneCount; int nTotalPanes = 0; for( int i = 0; i < m_nPanes; ++i ) { if( i + 1 == m_nPanes ) { // Assigned all remaining value to the last pane without computation. // This is done in order to prevent propagation of computation errors. m_size[i] = FULL_SIZE - nTotalPanes; } else { if( m_frozen[i] ) { // Frozen pane m_size[i] = MulDivRound( m_size[i], prev_size_sum, size_sum); } else { // Non frozen pane m_size[i] = MulDivRound( m_size[i], prev_size_sum, size_sum ) + MulDivRound( size_sum - prev_size_sum, FULL_SIZE, size_sum * non_frozen_count ); } } // If a pane become to small, it will be adjusted with the proportional algorithm. bFrozenOnly &= ( MulDivRound(m_size[i], size_sum, FULL_SIZE) <= m_pzMinSize[i] ); // Compute running sumof pane sizes. nTotalPanes += m_size[i]; } } /* The previous section might set the flag bFrozenOnly in case a pane became too small. In this case, we also want to execute this algorithm in order to respect the minimum pane size constraint. */ if( !bFrozenOnly ) { while (bGrow) // adjust sizes on the beginning { // and while we have growed something bGrow = false; remain = remain_new = FULL_SIZE; for (i = 0; i < m_nPanes; i++) // grow small panes to minimal size if ( MulDivRound(m_size[i], size_sum, FULL_SIZE) <= m_pzMinSize[i]) { remain -= m_size[i]; if (MulDivRound(m_size[i], size_sum, FULL_SIZE) < m_pzMinSize[i]) { if (m_pzMinSize[i] > size_sum) m_size[i] = FULL_SIZE; else m_size[i] = MulDivRound(m_pzMinSize[i], FULL_SIZE, size_sum); bGrow = true; } remain_new -= m_size[i]; } if (remain_new <= 0) // if there isn't place to all panes { // set the minimal size to the leftmost/topmost remain = FULL_SIZE; // and set zero size to the remainimg for (i = 0; i < m_nPanes; i++) { if (size_sum == 0) m_size[i] = 0; else m_size[i] = MulDivRound(m_pzMinSize[i], FULL_SIZE, size_sum); if (m_size[i] > remain) m_size[i] = remain; remain -= m_size[i]; } break; } if (remain_new != FULL_SIZE) // adjust other pane sizes, if we have growed some for (i = 0; i < m_nPanes; i++) if ( MulDivRound(m_size[i], size_sum, FULL_SIZE) != m_pzMinSize[i]) m_size[i] = MulDivRound(m_size[i], remain_new, remain); } } // calculate positions (in pixels) from relative sizes m_orig[0] = ( m_nOrientation == SSP_HORZ ? rcOuter.left:rcOuter.top ); for (i = 0; i < m_nPanes - 1; i++) m_orig[i + 1] = m_orig[i] + MulDivRound(m_size[i], size_sum, FULL_SIZE) + m_nBarThickness; m_orig[m_nPanes] = m_orig[0] + size_sum + m_nBarThickness * m_nPanes; }