BOOL CGuiControlBar::IsLegal(UINT uAlin) { m_First=GetFirstPos(); // if (IsFloating()) return FALSE; switch(uAlin) { case HTLEFT: if (IsHorz() && m_pos >0 && (m_pos != m_Last && m_pos != m_First)) return TRUE; if (IsVert() && m_pos <= m_Last && IsRight() ) return TRUE; return FALSE; break; case HTTOP: if (m_pos != m_First && IsVert()) return TRUE; if (IsHorz() && m_pos <= m_Last && IsBottom() ) return TRUE; return FALSE; break; case HTRIGHT: if (m_pos <= m_Last && IsVert() && IsLeft() ) return TRUE; if (IsHorz() && m_pos >0 && m_pos != m_Last) return TRUE; return FALSE; case HTBOTTOM: if ((m_pos != m_Last && m_pos != m_First) && IsHorz() && IsBottom()) return TRUE; if (m_pos <= m_Last && IsHorz() && IsTop()) return TRUE; //if (IsVert() && m_pos >0 ) return TRUE; return FALSE; break; } return FALSE; }
//ajusta las ventanas a redimencionarlas verticalmente //se decrementa las anteriores ventanas a la actual y se //incrementan las posteriores. void CGuiControlBar::AjustReDinSize(CPoint point) { int nFirstPos=GetFirstPos(); int nLastPos=GetLastPos(); int m_ThisPos=m_pDockBar->FindBar(this); ClientToScreen(&point); //si la diferencia es negativa esta barra crece la anterior a esta disminuye int nDif=0; BOOL bGrow=FALSE; if (IsVert()) { nDif=m_ptStartPos.y- point.y; if (nDif > 0) bGrow=TRUE; if (bGrow) m_sizeVert.cy+=abs(nDif)+4; else m_sizeVert.cy-=abs(nDif); if (nFirstPos == m_ThisPos) return; } else { nDif=m_ptStartPos.x- point.x; if (nDif < 0) bGrow=TRUE; if (bGrow) m_sizeHorz.cx+=abs(nDif); else m_sizeHorz.cx-=abs(nDif); if (nLastPos == m_ThisPos) return; } if (IsVert()) AjustVert(bGrow,nDif); else AjustHorz(bGrow,nDif); RecalWindowPos(); }
void CGuiControlBar::OnMouseMove( UINT nHitTest, CPoint point) { if(m_bTracking) { if (GetCapture() != this) { //StopTracking(FALSE); m_bTracking=FALSE; } OnInvertTracker(m_rcBorder); //nuevos tamaños de la ventana if (IsVert()) { if (m_SideMove==HTLEFT || m_SideMove==HTRIGHT) { m_rcBorder.left=point.x; m_rcBorder.right=m_rcBorder.left+4; } else { m_rcBorder.top=point.y+26; m_rcBorder.bottom=m_rcBorder.top+4; } } else { if (m_SideMove==HTBOTTOM || m_SideMove==HTTOP) { m_rcBorder.top=point.y+26; m_rcBorder.bottom=m_rcBorder.top+4; } else { m_rcBorder.left=point.x; m_rcBorder.right=m_rcBorder.left+4; } } //-------------------------------------------------- //se hacen iguales todos los tamaños ClientToScreen(&point); GetParentFrame()->ScreenToClient(&point); m_ptActualPos=point; OnInvertTracker(m_rcBorder); //SetEqualWidth(); //----------------------------------------------- } }
//***************************************************************************** void CBCGPRibbonSlider::SetThumbRect () { ASSERT_VALID (this); if (m_nMax <= m_nMin || m_rect.IsRectEmpty ()) { m_rectThumb.SetRectEmpty (); return; } m_rectThumb = m_rectSlider; double dblScale = globalData.GetRibbonImageScale (); if (IsVert ()) { double dy = ((double) m_rectSlider.Height ()) / (m_nMax - m_nMin); int yOffset = (int) (.5 + dy * (m_nPos - m_nMin)); int nThumbHeight = cyThumbHeight; int nSliderWidth = cxSliderWidth; if (dblScale > 1.) { nThumbHeight = (int)(.5 + dblScale * nThumbHeight) + 1; nSliderWidth = (int)(.5 + dblScale * nSliderWidth); } if (m_rectThumb.Width () > nSliderWidth) { m_rectThumb.left = m_rectThumb.CenterPoint ().x - nSliderWidth / 2; m_rectThumb.right = m_rectThumb.left + nSliderWidth; } if (dblScale > 1.) { m_rectThumb.DeflateRect (2, 0); } m_rectThumb.bottom -= yOffset - nThumbHeight / 2; m_rectThumb.top = m_rectThumb.bottom - nThumbHeight; } else { double dx = ((double) m_rectSlider.Width ()) / (m_nMax - m_nMin); int xOffset = (int) (.5 + dx * (m_nPos - m_nMin)); int nThumbWidth = cxThumbWidth; if (dblScale > 1.) { nThumbWidth = (int)(.5 + dblScale * nThumbWidth) + 1; m_rectThumb.DeflateRect (0, 2); } m_rectThumb.left += xOffset - nThumbWidth / 2; m_rectThumb.right = m_rectThumb.left + nThumbWidth; } }
void RulerCtrl::FrameAddSize(Size& sz) { if(IsShown()) { if(IsVert()) sz.cx += width; else sz.cy += width; } }
int CGuiControlBar::GetHiWid() { CRect rcWin; rcWin=GetDockRect(); if (IsVert()) return rcWin.Height() ; else return rcWin.Width() ; }
Size ScrollBar::GetReducedViewSize() const { if(IsChild() && InFrame()) { Size sz = GetParent()->GetSize(); if(!IsShown()) (IsVert() ? sz.cx : sz.cy) -= ScrollBarSize(); return sz; } return Size(0, 0); }
//en esta función se calcula el area cliente que podra ser utilizado //por ventanas que deriven esta clase. void CGuiControlBar::OnNcCalcSize(BOOL /*bCalcValidRects*/, NCCALCSIZE_PARAMS* lpncsp) { // adjust non-client area for border space lpncsp->rgrc[0].left +=!IsFloating()?5:2; lpncsp->rgrc[0].top +=nGapGripper+3; lpncsp->rgrc[0].right -=!IsFloating()?IsVert()?7:4:2; lpncsp->rgrc[0].bottom -=!IsFloating()?3:2; }
//*/ //工具栏一行中排不下时折行,bar是需要折行的第一个工具栏 int RingDockSite::WrapLine(RingDockBar* bar) { if(bar) { int *pos,x=0,y=0; int nSize = 0,nExtra = 0; LPRINGBARLINEINFO lpline = AddLine(bar->m_lineInfo); if(bar->m_prev) bar->m_prev->m_next = NULL; bar->m_prev = NULL; lpline->m_first = bar; if(IsVert()) { x = lpline->m_pos; pos = &y; } else { y = lpline->m_pos; pos = &x; } while(bar) { bar->m_lineInfo = lpline; bar->SetDockPos(x,y); if(bar->IsVisible()) { lpline->m_maxSize = max(lpline->m_maxSize,bar->m_nSize); if(IsVert()) *pos += (bar->m_rcDockPos.bottom - bar->m_rcDockPos.top); else *pos += (bar->m_rcDockPos.right - bar->m_rcDockPos.left); } bar = bar->m_next; } return lpline->m_maxSize; } return 0; }
void RingDockSite::DrawSite(HDC hDC,RINGPARAMS& param) { LPRINGBARLINEINFO tmp = m_First; RingDockBar* bar; //if(param.uMsg == WM_ERASEBKGND && !DrawBkg(hDC)) // DefaultProc(param); DrawBkg(hDC); if(m_State == TBS_FLAG_DOCKTOP && MASK_MATCH(m_parent->GetStyle(),WS_CAPTION) && tmp && tmp->isVisible) { //非底部且父窗口有标题栏,绘制最上一条横线 RECT rc = {0,0,m_rcPos.right,2}; DrawEdge(hDC,&rc,BDR_SUNKENOUTER,BF_TOP); DrawEdge(hDC,&rc,BDR_SUNKENOUTER,BF_BOTTOM); } while(tmp) { bar = tmp->m_first; while(bar) { //ExcludeClipRect(param.hdc,bar->m_rcClient.left,bar->m_rcClient.top, // bar->m_rcClient.right,bar->m_rcClient.bottom); if(!bar->Draw(hDC)) { OnDockBarHide(bar); bar->Show(bar->IsVisible()?SW_SHOW:SW_HIDE); return; } bar = bar->m_next; } if(tmp->isVisible && tmp->m_SplitRc.right != 0) { if(IsVert()) tmp->m_SplitRc.bottom = tmp->m_SplitRc.top + m_rcPos.bottom - m_rcPos.top; else tmp->m_SplitRc.right = tmp->m_SplitRc.left + m_rcPos.right - m_rcPos.left; DrawEdge(hDC,&tmp->m_SplitRc,BDR_RAISEDINNER,BF_RECT); DrawEdge(hDC,&tmp->m_SplitRc,BDR_RAISEDOUTER,BF_BOTTOMRIGHT); } tmp = tmp->m_nextline; } /*if(IsVert()) { RECT rc; GetClientRect(&rc); if(rc.right > 1) DrawEdge(hDC,&rc,BDR_SUNKENOUTER,BF_TOP); } */ }
BOOL RingDockSite::ParentReSize(int width,int height) { int nChk; if(IsVert()) { RingDockSite* tmp = ((RingWnd*)m_parent)->GetDockSite(TBS_FLAG_DOCKTOP); if(tmp) m_rcPos.top = tmp->m_rcPos.bottom; else m_rcPos.top = 0; tmp = ((RingWnd*)m_parent)->GetDockSite(TBS_FLAG_DOCKBOTTOM); if(tmp) m_rcPos.bottom = tmp->m_rcPos.top; else m_rcPos.bottom = height; if(m_State == TBS_FLAG_DOCKRIGHT) { m_rcPos.left = width - (m_rcPos.right - m_rcPos.left); m_rcPos.right = width; } //必须先调整尺寸,否则整行工具栏仍采用原尺寸为最大尺寸 nChk = MAKELONG(m_rcPos.left,m_rcPos.right); MoveWindow(m_hWnd,m_rcPos.left,m_rcPos.top,m_rcPos.right-m_rcPos.left,m_rcPos.bottom-m_rcPos.top,TRUE); AdjustChildrenV(m_rcPos.bottom-m_rcPos.top); //检查AdjustChildrenH是否调整了m_rcPos nChk = (nChk == MAKELONG(m_rcPos.left,m_rcPos.right)); } else { m_rcPos.right = width; if(m_State == TBS_FLAG_DOCKBOTTOM) { m_rcPos.top = height - (m_rcPos.bottom - m_rcPos.top); m_rcPos.bottom = height; } nChk = MAKELONG(m_rcPos.top,m_rcPos.bottom); //必须先调整尺寸,否则整行工具栏仍采用原尺寸为最大尺寸 MoveWindow(m_hWnd,m_rcPos.left,m_rcPos.top,m_rcPos.right-m_rcPos.left,m_rcPos.bottom-m_rcPos.top,TRUE); AdjustChildrenH(m_rcPos.right-m_rcPos.left); //检查AdjustChildrenH是否调整了m_rcPos nChk = (nChk == MAKELONG(m_rcPos.top,m_rcPos.bottom)); } if(nChk == 0) MoveWindow(m_hWnd,m_rcPos.left,m_rcPos.top,m_rcPos.right-m_rcPos.left,m_rcPos.bottom-m_rcPos.top,TRUE); return TRUE; }
//en esta función se calcula el area cliente que podra ser utilizado //por ventanas que deriven esta clase. void CGuiPanelWnd::OnNcCalcSize(BOOL /*bCalcValidRects*/, NCCALCSIZE_PARAMS* lpncsp) { // adjust non-client area for border space lpncsp->rgrc[0].left +=5; lpncsp->rgrc[0].top +=nGapGripper+3; if (IsVert()) lpncsp->rgrc[0].right -=5; else lpncsp->rgrc[0].right -=3; lpncsp->rgrc[0].bottom -=3; }
//***************************************************************************** CSize CBCGPRibbonSlider::GetRegularSize (CDC* pDC) { ASSERT_VALID (this); ASSERT_VALID (pDC); const BOOL bIsVert = IsVert (); CSize size (bIsVert ? max (m_nWidth, cxSliderWidth) : m_nWidth, bIsVert ? m_nWidth : cySliderHeight); if (IsQATMode () && (m_dwStyle & TBS_VERT)) { size.cx = 50; } double dblScale = globalData.GetRibbonImageScale (); if (bIsVert) { if (!m_strText.IsEmpty ()) { int nTextWidth = pDC->GetTextExtent (m_strText).cx; size.cx = max (size.cx, nTextWidth); } int nZoomButtonSize = cxSliderWidth; if (dblScale > 1.) { size.cx = (int)(.5 + dblScale * size.cx); nZoomButtonSize = (int)(.5 + dblScale * nZoomButtonSize); } if (m_bZoomButtons) { size.cy += 2 * nZoomButtonSize; } } else { if (dblScale > 1.) { size.cy = (int)(.5 + dblScale * size.cy); } if (m_bZoomButtons) { size.cx += 2 * size.cy; } } return size; }
//******************************************************************************** void CBCGPRibbonSlider::OnDraw (CDC* pDC) { ASSERT_VALID (this); ASSERT_VALID (pDC); if (m_rect.IsRectEmpty ()) { return; } if (m_bZoomButtons) { // Draw zoom buttons: CBCGPVisualManager::GetInstance ()->OnDrawRibbonSliderZoomButton ( pDC, this, m_rectZoomOut, TRUE, m_bIsHighlighted && m_nHighlighted == nZoomOutIndex, m_bIsPressed && m_nPressed == nZoomOutIndex, IsDisabled ()); CBCGPVisualManager::GetInstance ()->OnDrawRibbonSliderZoomButton ( pDC, this, m_rectZoomIn, FALSE, m_bIsHighlighted && m_nHighlighted == nZoomInIndex, m_bIsPressed && m_nPressed == nZoomInIndex, IsDisabled ()); } // Draw channel: CRect rectChannel = m_rectSlider; if (IsVert ()) { rectChannel.left = rectChannel.CenterPoint ().x - 1; rectChannel.right = rectChannel.left + 2; } else { rectChannel.top = rectChannel.CenterPoint ().y - 1; rectChannel.bottom = rectChannel.top + 2; } CBCGPVisualManager::GetInstance ()->OnDrawRibbonSliderChannel ( pDC, this, rectChannel); // Draw thumb: CBCGPVisualManager::GetInstance ()->OnDrawRibbonSliderThumb ( pDC, this, m_rectThumb, (m_bIsHighlighted && (m_nHighlighted == nThumbIndex || m_nHighlighted == nSliderIndex)) || IsFocused (), m_bIsPressed && m_nPressed == nThumbIndex, IsDisabled ()); if (!m_rectLabel.IsRectEmpty () && !m_strText.IsEmpty ()) { DoDrawText (pDC, m_strText, m_rectLabel, DT_CENTER | DT_SINGLELINE); } }
//espero que funcione el truco //la idea es trabajar con coordenadas screen las dimensiones de los bordes del //dockBar, mas no con los movimientos internos. void CGuiControlBar::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CPoint ptTemp=point; ClientToScreen(&ptTemp); if (m_bTracking) { ReleaseCapture(); m_bTracking=FALSE; OnInvertTracker(m_rcBorder); m_pDockSite->UnlockWindowUpdate(); if (ptTemp ==m_ptStartPos) return; if (IsVert()) { if (m_SideMove==HTLEFT) m_sizeVert.cx-=point.x; else if(m_SideMove==HTRIGHT) m_sizeVert.cx=point.x; else if(m_SideMove==HTTOP) AjustReDinSize(point); } else { if (m_SideMove==HTBOTTOM) { if (point.y < 0) m_sizeHorz.cy+=abs(point.y); else m_sizeHorz.cy=point.y; } else if (m_SideMove==HTTOP) { if (point.y < 0) m_sizeHorz.cy+=abs(point.y)-12; else m_sizeHorz.cy-=abs(point.y)+12; } else if (m_SideMove==HTRIGHT) AjustReDinSize(point); } SetEqualWidth(); } m_pDockSite->RecalcLayout(); }
int CGuiControlBar::GetWidthMax() { m_pos=m_pDockBar->FindBar(this); m_Last=GetLastPos(); int nWidth=0; for (int nPos = GetFirstPos(); nPos <= m_Last; nPos++) { CGuiControlBar* pBar = GetGuiControlBar(nPos); if (pBar== NULL) continue; nWidth=max(nWidth,IsVert() ? pBar->m_sizeVert.cx:pBar->m_sizeHorz.cy); } return nWidth; }
CRect CGuiControlBar::GetDockRect() { CRect rcWin; if (IsVert()) if (IsLeft()) m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_LEFT)->GetWindowRect(rcWin); else m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_RIGHT)->GetWindowRect(rcWin); else if(IsBottom()) m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_BOTTOM)->GetWindowRect(rcWin); else m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_TOP)->GetWindowRect(rcWin); return rcWin; }
//esta rutina dispone de la posición en el Dockbar de la pila de ventanas void CGuiControlBar::RecalWindowPos() { int m_First=GetFirstPos(); int m_Last=GetLastPos(); int m_This=m_pDockBar->FindBar(this); CRect rcWin=GetDockRect(); int m_VertPos=0; for(int i=m_First; i<= m_Last; i++) { CGuiControlBar* pBar = GetGuiControlBar(i); if (pBar == NULL) continue; CRect rcBar; pBar->GetWindowRect(rcBar); rcBar.OffsetRect(-rcWin.TopLeft()); if (IsVert()) { if (i==m_First) rcBar.top=-2; else rcBar.top=m_VertPos; } else { if (i==m_First) rcBar.left=-2; else rcBar.left=m_VertPos; } pBar->MoveWindow(rcBar); m_VertPos+=IsVert()? rcBar.Height():rcBar.Width(); } m_pDockSite->RecalcLayout(); }
void CGuiToolBarWnd::SetRealSize() { CRect rcWinFrame; CRect rcThisBar; int nVisibles=0; int nThis = m_pDockBar->FindBar(this); int nFirst= GetFirstPos(); int nLast= GetLastPos(); UINT m_nDockBarID = m_pDockBar->GetDlgCtrlID(); int nMaxlen=GetHiWid(); int nLen=0; for (int i=nFirst;i <nLast; i++) { CGuiToolBarWnd* pBar; pBar = (CGuiToolBarWnd*) m_pDockBar->m_arrBars[i]; if (HIWORD(pBar) == 0) continue; if (!pBar->IsVisible()) continue; CRect rc; pBar->GetWindowRect(rc); if (IsVert()) nLen+=rc.Height() ; else nLen+= rc.Width() ; nVisibles++; } if ( nLen > nMaxlen) { int nDif=nLen-nMaxlen; } /* if (rcThisBar.Width() > nAfterThis) { if (nVisibles > 0) nAfterThis/=nVisibles; } */ }
void RingDockSite::UpdateLine(LPRINGBARLINEINFO lpline,int nStep,BOOL bUpdate/*=TRUE*/) { //调整位于lpline后面的边线框位置 LPRINGBARLINEINFO tmp; //RingDockBar* bar; int lastpos = 0,step; if(lpline == NULL || lpline == m_First) { tmp = m_First; //检测调整线是否在最上或最左位置 //if(tmp && tmp->m_SplitRc.right != 0 && ((m_State & 1) == 1)) // lastpos = RING_SPLITERSIZE; } else { tmp = lpline; lastpos = tmp->m_pos; if(tmp && tmp->m_SplitRc.right != 0 && ((m_State & 1) == 1)) lastpos -= RING_SPLITERSIZE; } while(tmp) { step = lastpos - tmp->m_pos; tmp->m_pos = lastpos; if(tmp->m_SplitRc.right != 0) { //有分隔线且为下或右方停靠 if((m_State & 0x1) == 1)// && tmp != m_First) { step += RING_SPLITERSIZE; tmp->m_pos += RING_SPLITERSIZE; } lastpos += RING_SPLITERSIZE; if(IsVert()) OffsetRect(&tmp->m_SplitRc,step,0); else OffsetRect(&tmp->m_SplitRc,0,step); } lastpos += tmp->m_maxSize; tmp = tmp->m_nextline; } UpdatePos(nStep,bUpdate); }
Size DockTabBar::GetStdSize(const Tab &t) { DockableCtrl *d; const Value &q = t.key; Value v; if (IsTypeRaw<DockCont *>(q)) { DockCont *c = ValueTo<DockCont *>(q); d = &c->GetCurrent(); v = c->GetTitle(); } else { ASSERT(IsTypeRaw<DockableCtrl *>(q)); d = ValueTo<DockableCtrl *>(q); v = d->GetTitle(); } int isz = (IsVert() ? d->GetIcon().GetHeight() : d->GetIcon().GetWidth()); return showtext ? (TabBar::GetStdSize(v) + Size(isz+2, 0)) : Size(isz, isz); }
void RulerCtrl::FrameLayout(Rect& rc) { Rect pos = rc; int wd = (IsShown() ? width : 0); if(IsVert()) { if(IsBottomRight()) rc.right = max(rc.left, pos.left = rc.right - wd); else rc.left = min(rc.right, pos.right = pos.left + wd); } else { if(IsBottomRight()) rc.bottom = max(rc.top, pos.top = pos.bottom - wd); else rc.top = min(rc.bottom, pos.bottom = pos.top + wd); } SetFrameRect(pos); }
void AutoHideBar::ShowAnimate(Ctrl *c) { if (c == ctrl) return; if (popup.IsPopUp()) popup.Close(); Rect target = Ctrl::GetScreenRect(); Size sz = c->GetStdSize(); switch (GetAlign()) { case DockTabBar::LEFT: sz.cy = target.Height(); target.left = target.right; break; case DockTabBar::TOP: sz.cx = target.Width(); target.top = target.bottom; break; case DockTabBar::RIGHT: sz.cy = target.Height(); target.right = target.left; break; case DockTabBar::BOTTOM: sz.cx = target.Width(); target.bottom = target.top; break; }; if (IsVert()) sz.cx = min(sz.cx, GetParent()->GetSize().cx / 2); else sz.cy = min(sz.cy, GetParent()->GetSize().cy / 2); Rect init = target; AdjustSize(init, Size(5, 5)); AdjustSize(target, sz); c->SetRect(sz); c->SizePos(); popup << *(ctrl = c); c->Show(); popup.SetRect(target); popup.PopUp(GetParent(), false, true, false, false); Animate(popup, target, GUIEFFECT_SLIDE); }
LRESULT RingDockSite::OnLButtonUp(RINGPARAMS& param) { SetCursor(m_windowInfo.hCursor); if(m_CaptureBar) { m_CaptureBar->StopDrag(m_parent->Handle(),&m_dragger,param); m_CaptureBar = NULL; } else if(m_dragger.IsDragging()) { int nStep; LPRECT lprc = m_dragger.StopDrag(m_hWnd,param.mousept.x,param.mousept.y); if(IsVert()) { nStep = lprc->left - m_Curr->m_SplitRc.left; if(m_State == TBS_FLAG_DOCKRIGHT) nStep = -nStep; else CopyRect(&m_Curr->m_SplitRc,lprc); } else { nStep = lprc->top - m_Curr->m_SplitRc.top; if(m_State == TBS_FLAG_DOCKBOTTOM) nStep = -nStep; else CopyRect(&m_Curr->m_SplitRc,lprc); } m_Curr->m_maxSize += nStep; UpdateLine(m_Curr,nStep); } return 0; }
//***************************************************************************** int CBCGPRibbonSlider::GetPosFromPoint (CPoint pt) { ASSERT_VALID (this); if (m_nMax <= m_nMin || m_rect.IsRectEmpty ()) { return m_nMin; } if (IsVert ()) { const double dy = ((double) m_rectSlider.Height ()) / (m_nMax - m_nMin); const int yOffset = m_rectSlider.bottom - pt.y; return m_nMin + (int) ((double) yOffset / dy); } else { const double dx = ((double) m_rectSlider.Width ()) / (m_nMax - m_nMin); const int xOffset = pt.x - m_rectSlider.left; return m_nMin + (int) ((double) xOffset / dx); } }
//在行内添加工具栏 int RingDockSite::AddBarInLine(RingDockBar* dockbar,LPRINGBARLINEINFO lpline,LPRECT lprc/*=NULL*/) { if(dockbar == NULL || lpline == NULL) return 0; RECT rc; if(lprc == NULL) lprc = &rc; dockbar->m_prev = dockbar->m_next = NULL; dockbar->m_lineInfo = lpline; if(IsVert()) { rc.left = lpline->m_pos; rc.right = rc.left + dockbar->m_rcDockPos.right - dockbar->m_rcDockPos.left; OffsetRect(lprc,lpline->m_pos - lprc->left,0); if(lpline->m_first == NULL) { rc.top = 0; rc.bottom = dockbar->m_rcDockPos.bottom - dockbar->m_rcDockPos.top; lpline->m_first = dockbar; RingDockSite* pSite = ((RingWnd*)m_parent)->GetDockSite(TBS_FLAG_DOCKBOTTOM); int nEdge; //工具栏有可能是从底部移过来,且底部DockSite有可能缩小高度,而此时本DockSite //的高度尚未变化,因此需依据底部DockSite尺寸判断 if(pSite) nEdge = pSite->m_rcPos.top; else nEdge = m_rcPos.bottom; if(lprc->bottom > m_rcPos.bottom) OffsetRect(lprc,0,nEdge - lprc->bottom); if(lprc->top < 0) OffsetRect(lprc,0,-lprc->top); dockbar->SetDockPos(lprc->left,lprc->top); rc.left = lpline->m_maxSize; lpline->m_maxSize = dockbar->m_nSize; InvalidateRect(m_hWnd,NULL,TRUE); return lpline->m_maxSize - rc.left; } else { rc.top = 9999; rc.bottom = 9999 + dockbar->m_rcDockPos.bottom - dockbar->m_rcDockPos.top; return AddBarInLineV(dockbar,lpline,lprc,(lprc->top + lprc->bottom)/2); } } else { rc.top = lpline->m_pos; rc.bottom = rc.top + dockbar->m_rcDockPos.bottom - dockbar->m_rcDockPos.top; OffsetRect(lprc,0,lpline->m_pos - lprc->top); if(lpline->m_first == NULL) { rc.left = 0; rc.right = dockbar->m_rcDockPos.right - dockbar->m_rcDockPos.left; lpline->m_first = dockbar; if(lprc->right > m_rcPos.right - m_rcPos.left) OffsetRect(lprc,m_rcPos.right - m_rcPos.left - lprc->right,0); if(lprc->left < 0) OffsetRect(lprc,-lprc->left,0); dockbar->SetDockPos(lprc->left,lprc->top); rc.left = lpline->m_maxSize; lpline->m_maxSize = dockbar->m_nSize; InvalidateRect(m_hWnd,NULL,TRUE); return lpline->m_maxSize - rc.left;//lpline->m_maxSize; } else { rc.left = 9999; rc.right = 9999 + dockbar->m_rcDockPos.right - dockbar->m_rcDockPos.left; return AddBarInLineH(dockbar,lpline,lprc,(lprc->left + lprc->right)/2); } } }
///////////////////////////////////////////////////////////// // //加入工具栏,工具栏必须是本窗口的子窗口且dockbar已调用SetDockSite加入到本停靠坞 //函数自动判断该工具栏是新加入或需要调整位置 //lprc为相对于父窗口坐标 // ///////////////////////////////////////////////////////////// BOOL RingDockSite::AddBar(RingDockBar* dockbar,LPRECT lprc) { if(dockbar && dockbar->m_pSite == this) { int m,nSize,nDel=0; LPRINGBARLINEINFO tmp = NULL; LPRINGBARLINEINFO lpline = NULL; BOOL bLast = FALSE; RECT rc; if(lprc) { CopyRect(&rc,lprc); MapWindowPoints(m_parent->Handle(),m_hWnd,(LPPOINT)&rc,2); lprc = &rc; //指定位置停靠,先根据lprc的中线判断停靠位置 if(IsVert()) { if(dockbar->IsAllLineBar()) { m = lprc->left; lprc = NULL; } else m = (lprc->left + lprc->right)/2; } else { if(dockbar->IsAllLineBar()) { m = lprc->top; lprc = NULL; } else m = (lprc->top + lprc->bottom)/2; } } else m = 9999; //加到最后 //寻找要停靠的行 lpline = GetDockLine(m); LPRINGBARLINEINFO save = dockbar->m_lineInfo; if(save) //已停靠在本窗口位置 { nDel = BarOutLine(dockbar,(lpline != save),tmp); if(tmp == NULL && lpline != save) { //要删除行 DelLine(save); } } nSize = AddBarInLine(dockbar,lpline,lprc); if(dockbar->IsSizeBar()) { if(lpline->m_nSizeBarCnt == 0) nSize += m_SplitterSize; lpline->m_nSizeBarCnt ++; if(lprc == NULL) //第一次加入 dockbar->InitDockSize(); SetSizeSplitRect(lpline); } UpdateLine(NULL,nSize + nDel); return TRUE; } else return FALSE; }
void CGuiControlBar::AjustVert(BOOL bGrow,int nDif) { int nFirstPos=GetFirstPos(); int nLastPos=GetLastPos(); int m_ThisPos=m_pDockBar->FindBar(this); if(m_SideMove==HTTOP) { //Esta ventana crece las anteriores reducen su tamaño if (bGrow) { for (int i=m_ThisPos-1; i > 0; i--) { CGuiControlBar* pBar = GetGuiControlBar(i); if (pBar== NULL) return; if(IsVert()) { if (pBar->m_sizeVert.cy-abs(nDif) < pBar->m_sizeMinV.cy) { pBar->m_sizeVert.cy=pBar->m_sizeMinV.cy; continue; } else { pBar->m_sizeVert.cy-=abs(nDif); break; } } }//for }//bGrow else //este disminuye la anterior crece { if (m_ThisPos-1 > 0) { CGuiControlBar* pBar = GetGuiControlBar(m_ThisPos-1); if (pBar== NULL) return; pBar->m_sizeVert.cy+=abs(nDif); if(m_sizeVert.cy > m_sizeMinV.cy) return; else pBar->m_sizeVert.cy-=m_sizeMinV.cy; } for (int i=m_ThisPos+1; i >= m_Last; i++) { CGuiControlBar* pBar = GetGuiControlBar(i); if (pBar== NULL) return; if(IsVert()) { if (pBar->m_sizeVert.cy-abs(nDif) < pBar->m_sizeMinV.cy) continue; else { pBar->m_sizeVert.cy-=abs(nDif); return; } } }//for } } }
void CGuiControlBar::OnInvertTracker(const CRect& rect) { ASSERT_VALID(this); ASSERT(!rect.IsRectEmpty()); CRect rcWin=GetDockRect(); CDC *pDC = m_pDockSite->GetDCEx(NULL, DCX_WINDOW|DCX_CACHE|DCX_LOCKWINDOWUPDATE); CRect rcBar; GetWindowRect(rcBar); if (IsVert()) //el sentido de las barras es vertical { if (m_SideMove==HTLEFT || m_SideMove==HTRIGHT) //el mouse esta en el borde izquierdo o derecho { rcWin.OffsetRect(-rect.left,-rect.top); rcWin.top+=10; rcWin.left=rect.left+2; rcWin.right=rect.right+2; } else //el mouse esta el borde de arriba pero de una barra vertical { rcBar.OffsetRect(-rect.TopLeft()); rcWin=rcBar; if (IsLeft() || IsRight()) //a la izquierda { rcWin.top=rect.top-2; rcWin.bottom=rect.bottom-2; } // } } else //el sentido de las barras es horizontal { if (m_SideMove==HTTOP || m_SideMove==HTBOTTOM) //el mouse esta en el borde de arriba o abajo { rcWin.OffsetRect(-rect.left,-rect.top); rcWin.top=rect.top-2; rcWin.bottom=rect.bottom-2; } else //el mouse esta en el borde derecho { rcBar.OffsetRect(-rect.TopLeft()); rcWin=rcBar; if (IsBottom() || IsTop()) //abajo { rcWin.left=rect.left+2; rcWin.right=rect.right+2; } } } ClientToScreen(&rcWin); GetParentFrame()->ScreenToClient(&rcWin); // invert the brush pattern (looks just like frame window sizing) CBrush* pBrush = CDC::GetHalftoneBrush(); HBRUSH hOldBrush = NULL; if (pBrush != NULL) hOldBrush = (HBRUSH)SelectObject(pDC->m_hDC, pBrush->m_hObject); pDC->PatBlt(rcWin.left, rcWin.top, rcWin.Width(), rcWin.Height(), PATINVERT); if (hOldBrush != NULL) SelectObject(pDC->m_hDC, hOldBrush); m_pDockSite->ReleaseDC(pDC); }
//esta funcion calcula el tamaño horizontal de la ventana,no importa si esta //docking a izquierda o derecha o arriba o abajo.Debemos disponer de un espacio equitativo entre todas //ventanas que se encuentren docking ya sea en una fila o columna. CSize CGuiControlBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz) { //la funcion original toma el ancho o alto dependiendo del sentido que nos //indica bHorz. ASSERT_VALID(this); if (IsFloating()) return m_sizeMinFloating; else { //si bStrerch es TRUE significa que esta ventana no se puede hacer //Docking if (bStretch) { if (bHorz) return CSize(32767, m_sizeHorz.cy); else return CSize(m_sizeVert.cx, 32767); } } int Len=GetHiWid(); int nWidth = GetWidthMax(); int nMinSpace=0;//minimo espacio requerido con lo tamaños normales int nMinimo=0; //minimo espacio de los tamaños minimos int nRealBars=0; int m_First=GetFirstPos(); for (int nPos = m_First; nPos <= m_Last; nPos++) { CGuiControlBar* pBar = GetGuiControlBar(nPos,TRUE); if (pBar== NULL) continue; if (!pBar->IsVisible()) continue; if (!pBar->IsKindOf(RUNTIME_CLASS(CGuiControlBar))) { CPoint pt(GetMessagePos()); m_pDockSite->FloatControlBar(pBar,pt); continue; } if(IsVert()) pBar->m_sizeVert.cx=nWidth; else pBar->m_sizeHorz.cy=nWidth; //todas se hacen con el mismo ancho nMinSpace+=IsVert() ? pBar->m_sizeVert.cy:pBar->m_sizeHorz.cx; //minimo espacio para alinear las barras nRealBars++; //cuantas barras realmente existen } //si el tamaño de las barras en la fila es mayor que //el espacio disponible, luego la solucion salomonica es //repartir el espacio entre todas. if (nRealBars == 1 ) { if (bHorz) return m_sizeHorz= CSize(Len,m_sizeHorz.cy); else return m_sizeVert=CSize(m_sizeVert.cx,Len); } int nDif=Len-nMinSpace; if (abs(nDif) !=0) { BOOL bGrow=FALSE; if (nDif > 0) bGrow=TRUE; nDif=abs(nDif); while(nDif > 0) { for (int nPos = m_First; nPos <= m_Last; nPos++) { CGuiControlBar* pBar = GetGuiControlBar(nPos); if (pBar== NULL) continue; if(IsVert()) { if(bGrow) pBar->m_sizeVert.cy+=1; else { if (pBar->m_sizeVert.cy-1 < pBar->m_sizeMinV.cy) continue; pBar->m_sizeVert.cy-=1; } } else { if(bGrow) pBar->m_sizeHorz.cx+=1; else { if (pBar->m_sizeHorz.cx-1 < pBar->m_sizeMinH.cx) continue; pBar->m_sizeHorz.cx-=1; } } nDif--; if(nDif==0) break; } } } //--reubicar las ventanas, sin esta rutina nada funciona RecalWindowPos(); if (IsHorz()) return m_sizeHorz; else return m_sizeVert; }