- // P4PaneView.cpp : implementation file
- //
- #include "stdafx.h"
- #include "p4win.h"
- #include "P4PaneView.h"
- #include "P4PaneContent.h"
- #include "MainFrm.h"
- #include "ImageList.h"
- #include <afxpriv.h>
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CP4PaneView
- const int ID_CAPTION = 222;
- IMPLEMENT_DYNCREATE(CP4PaneView, CView)
- BEGIN_MESSAGE_MAP(CP4PaneView, CView)
- ON_WM_SETFOCUS()
- ON_WM_SIZE()
- ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
- ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
- ON_WM_CREATE()
- ON_MESSAGE( WM_FINDPATTERN, OnFindPattern )
- ON_BN_CLICKED( ID_CAPTION, LButtonClk )
- ON_BN_DOUBLECLICKED( ID_CAPTION, LButtonDblClk )
- ON_WM_SYSCOLORCHANGE()
- ON_MESSAGE( WM_ACTIVATEMODELESS, OnActivateModeless )
- END_MESSAGE_MAP()
- CP4PaneView::CP4PaneView()
- : m_content(0)
- {
- }
- CP4PaneView::~CP4PaneView() {}
- void CP4PaneView::SetBranchWnd(CWnd *wnd) { m_content->SetBranchWnd(wnd); }
- void CP4PaneView::SetChangeWnd(CWnd *wnd) { m_content->SetChangeWnd(wnd); }
- void CP4PaneView::SetClientWnd(CWnd *wnd) { m_content->SetClientWnd(wnd); }
- void CP4PaneView::SetDepotWnd(CWnd *wnd) { m_content->SetDepotWnd(wnd); }
- void CP4PaneView::SetJobWnd(CWnd *wnd) { m_content->SetJobWnd(wnd); }
- void CP4PaneView::SetLabelWnd(CWnd *wnd) { m_content->SetLabelWnd(wnd); }
- void CP4PaneView::SetOldChgWnd(CWnd *wnd) { m_content->SetOldChgWnd(wnd); }
- void CP4PaneView::SetUserWnd(CWnd *wnd) { m_content->SetUserWnd(wnd); }
- void CP4PaneView::OnInitialUpdate()
- {
- CView::OnInitialUpdate();
- // for some reason, list views end up with client edge style set
- // and we don't want it for any views
- ModifyStyleEx(WS_EX_CLIENTEDGE, 0);
- // want tooltips for caption
- m_reBar.SetBarStyle(CBRS_ALIGN_TOP |CBRS_TOOLTIPS);
- // don't want separator bar between caption and toolbar bands
- m_reBar.ModifyStyle(RBS_BANDBORDERS, 0);
- // put dropdown arrows on dropdown buttons
- m_toolBar.GetToolBarCtrl().SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS);
- // set owner to mainframe so tooltips status bar messages will work
- m_toolBar.SetOwner(AfxGetApp()->m_pMainWnd);
- // make it flat and transparent so it looks good on XP
- m_toolBar.ModifyStyle(0, TBSTYLE_FLAT|TBSTYLE_TRANSPARENT);
- // get rid of extra space around buttons
- m_toolBar.SetBorders();
- // set style to get tooltips working
- m_toolBar.SetBarStyle(CBRS_ALIGN_TOP | CBRS_TOOLTIPS | CBRS_FLYBY);
- // created non-visible so styles could be set before showing, so show now
- m_toolBar.ShowWindow(SW_SHOW);
- // set image list(s) for the toolbar
- m_toolBar.GetToolBarCtrl().SetImageList(
- TheApp()->GetToolBarImageList());
- m_toolBar.GetToolBarCtrl().SetDisabledImageList(
- TheApp()->GetToolBarImageList()->GetDisabled());
- // must set button size before adding buttons
- CSize sizeImage(18, 16);
- CSize sizeButton(18 + 7, 16 + 7);
- m_toolBar.SetSizes(sizeButton, sizeImage);
- // add the buttons to the toolbar
- SetToolBarButtons();
- // make the caption control transparent so the rebar will
- // draw the background under it
- m_captionCtrl.ModifyStyleEx(0, WS_EX_TRANSPARENT);
- // put the bands into the rebar
- // the ' ' text for the caption provides a little space on the left
- m_reBar.AddBar(&m_captionCtrl, _T(" "), NULL, RBBS_NOGRIPPER);
- m_reBar.AddBar(&m_toolBar, NULL, NULL, RBBS_NOGRIPPER|RBBS_FIXEDBMP);
- // determine how tall the bar should be to fit the taller of
- // the caption band or the toolbar band
- CRect r;
- r.SetRectEmpty();
- m_reBar.CalcInsideRect(r, TRUE);
- m_barHeight = max(16 + 7, GetSystemMetrics(SM_CYCAPTION));
- m_barHeight -= r.Height();
- m_contentTop = m_barHeight + GetSystemMetrics(SM_CYEDGE);
- // set up min/max sizes and ideal sizes for pieces of the rebar
- REBARBANDINFO rbbi;
- rbbi.cbSize = sizeof(rbbi);
- // set title band so it will be as wide as possible
- // and with a min size of one, it will never disappear
- // since the caption control will use the standard caption
- // font, it should be as tall as a standard caption.
- rbbi.fMask = RBBIM_CHILDSIZE | RBBIM_IDEALSIZE | RBBIM_SIZE;
- rbbi.cxMinChild = 1;
- rbbi.cyMinChild = GetSystemMetrics(SM_CYCAPTION);
- rbbi.cx = rbbi.cxIdeal = 20000; // want to be really big!
- m_reBar.GetReBarCtrl().SetBandInfo(0, &rbbi);
- // set max size for toolbar band to it's actual size
- // and min size to same so it won't be crowded out by
- // caption.
- m_toolBar.GetWindowRect(&r);
- rbbi.fMask = RBBIM_CHILDSIZE | RBBIM_IDEALSIZE | RBBIM_SIZE;
- rbbi.cxMinChild = r.Width();
- rbbi.cyMinChild = 16 + 7;
- rbbi.cx = rbbi.cxIdeal = r.Width();
- m_reBar.GetReBarCtrl().SetBandInfo(1, &rbbi);
- // reposition the bars, now that their sizes have been set
- GetClientRect(&r);
- r.bottom = m_barHeight;
- RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 1,
- reposDefault, NULL, &r);
- // and reposition the content, allowing space for the rebar edge
- GetContentWnd()->MoveWindow(0,m_contentTop,
- r.Width(),r.Height() - m_contentTop,TRUE);
- EnableToolTips();
- if (GET_P4REGPTR( )->SwapButtonPosition())
- SwapButtonPosition();
- }
- void CP4PaneView::OnSize(UINT nType, int cx, int cy)
- {
- CView::OnSize(nType, cx, cy);
- // don't do other sizing until created
- if(!IsWindow(m_toolBar.m_hWnd) || !m_reBar.GetReBarCtrl().GetBandCount())
- return;
- // put toolbar at top, list below it
- CRect r;
- r.SetRect(0, 0, cx, m_barHeight);
- RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 1,
- reposDefault, NULL, &r);
- // RepositionBars won't leave space between the rebar and the content
- // so we need to re-move the content to make space needed for the border
- GetContentWnd()->MoveWindow(0, m_contentTop, cx, cy - m_contentTop, TRUE);
- }
- void CP4PaneView::OnDraw(CDC* pDC)
- {
- // just draw an edget between the toolbar and the content
- CRect r;
- GetClientRect(&r);
- r.bottom = r.top + m_contentTop;
- pDC->DrawEdge(&r, EDGE_RAISED, BF_RECT);
- }
- void CP4PaneView::OnSetFocus(CWnd* pOldWnd)
- {
- CView::OnSetFocus(pOldWnd);
- if(GetContentWnd() && IsWindow(GetContentWnd()->m_hWnd))
- GetContentWnd()->SetFocus();
- }
- BOOL CP4PaneView::OnCmdMsg(UINT nID, int nCode, void* pExtra,
- AFX_CMDHANDLERINFO* pHandlerInfo)
- {
- if(GetContentWnd()->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
- return TRUE;
- return CView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
- }
- BOOL CP4PaneView::OnToolTipText( UINT id, NMHDR * pNMHDR, LRESULT * pResult )
- {
- // first, check for special case of caption control
- // and handle it here
- TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;
- UINT nID =pNMHDR->idFrom;
- if (pTTT->uFlags & TTF_IDISHWND)
- {
- // idFrom is actually the HWND of the tool
- nID = ::GetDlgCtrlID((HWND)nID);
- if(nID == ID_CAPTION)
- {
- m_captionCtrl.GetWindowText(m_captionTxt);
- pTTT->lpszText = (LPTSTR)(LPCTSTR)m_captionTxt;
- pTTT->hinst = NULL;
- return TRUE;
- }
- }
- // for other cases, just pass it along to mainframe
- CMainFrame *mainFrame = (CMainFrame *) AfxGetApp()->m_pMainWnd;
- return mainFrame->OnToolTipText(id, pNMHDR, pResult);
- }
- int CP4PaneView::GetSelectedItem()
- {
- CP4ListCtrl * pList = DYNAMIC_DOWNCAST(CP4ListCtrl, GetContentWnd());
- ASSERT(pList);
- if(pList)
- return pList->GetSelectedItem();
- return 0;
- }
- void CP4PaneView::OnEditPaste( const CString &Name )
- {
- CP4ListCtrl * pList = DYNAMIC_DOWNCAST(CP4ListCtrl, GetContentWnd());
- ASSERT(pList);
- if(pList)
- pList->OnEditPaste(Name);
- }
- CString CP4PaneView::GetSelectedItemText( )
- {
- CP4ListCtrl * pList = DYNAMIC_DOWNCAST(CP4ListCtrl, GetContentWnd());
- ASSERT(pList);
- if(pList)
- return pList->GetSelectedItemText();
- return "";
- }
- HTREEITEM CP4PaneView::GetSelectedItem(int index)
- {
- CMultiSelTreeCtrl * pTree = DYNAMIC_DOWNCAST(CMultiSelTreeCtrl, GetContentWnd());
- ASSERT(pTree);
- if(pTree)
- return pTree->GetSelectedItem(index);
- return 0;
- }
- CString CP4PaneView::GetItemText(HTREEITEM curr_item)
- {
- CMultiSelTreeCtrl * pTree = DYNAMIC_DOWNCAST(CMultiSelTreeCtrl, GetContentWnd());
- ASSERT(pTree);
- if(pTree)
- return pTree->GetItemText(curr_item);
- return "";
- }
- void CP4PaneView::SetCaption()
- {
- m_captionCtrl.SetWindowText(m_content->GetCaption());
- // Getting this updated is a bit complicated since the caption
- // control is transparent (to allow the rebar background to
- // show through). First, redraw the rebar, then the caption control.
- m_reBar.InvalidateRect(NULL);
- m_reBar.UpdateWindow();
- m_captionCtrl.InvalidateRect(NULL);
- m_captionCtrl.UpdateWindow();
- }
- int CP4PaneView::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if (CView::OnCreate(lpCreateStruct) == -1)
- return -1;
- if(!m_reBar.Create(this))
- return -1;
- if(!m_toolBar.Create(this,WS_CHILD | CBRS_ALIGN_TOP))
- return -1;
- if(!m_captionCtrl.Create(_T(""),WS_CHILD|WS_VISIBLE|BS_OWNERDRAW|BS_NOTIFY,
- CRect(0,0,1,1),this,ID_CAPTION))
- return -1;
- if(!CreateContent())
- return -1;
- LOGFONT lf;
- m_reBar.GetFont()->GetLogFont(&lf);
- m_inactiveFont.CreateFontIndirect(&lf);
- lf.lfWeight = FW_BOLD;
- m_activeFont.CreateFontIndirect(&lf);
- // Register that we accept Exploder files
- try
- {
- m_DropTarget.Register(this);
- }
- catch(...)
- {
- return 0;
- }
- return 0;
- }
- void CP4PaneView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView)
- {
- if(GetContentWnd() && IsWindow(GetContentWnd()->m_hWnd))
- {
- // force UI update right away, so if activation is caused by
- // click on toolbar dropdown, it can be enabled before the
- // toolbar gets the click message. Without this, it takes
- // one click to activate and another to drop down.
- m_toolBar.SendMessage(WM_IDLEUPDATECMDUI, (WPARAM)TRUE, 0);
- if(bActivate)
- {
- m_captionCtrl.SetFont(&m_activeFont);
- }
- else
- {
- m_captionCtrl.SetFont(&m_inactiveFont);
- }
- // The size of the caption text will change with the font change
- // so force an update
- SetCaption();
- }
- CView::OnActivateView(bActivate, pActivateView, pDeactiveView);
- }
- DROPEFFECT CP4PaneView::OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
- {
- MapWindowPoints(GetContentWnd(), &point, 1);
- return m_content->OnDragEnter(pDataObject, dwKeyState, point);
- }
- void CP4PaneView::OnDragLeave()
- {
- m_content->OnDragLeave();
- }
- DROPEFFECT CP4PaneView::OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
- {
- MapWindowPoints(GetContentWnd(), &point, 1);
- return m_content->OnDragOver(pDataObject, dwKeyState, point);
- }
- BOOL CP4PaneView::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
- {
- MapWindowPoints(GetContentWnd(), &point, 1);
- return m_content->OnDrop(pDataObject, dropEffect, point);
- }
- void CP4PaneView::SwapButtonPosition()
- {
- // swap the bands
- m_reBar.GetReBarCtrl().MoveBand(1, 0);
- // for some inexplicable reason, MoveBand doesn't update the bar
- // immediately. It takes some other action to make it actually update
- // and this seems like the least disruptive thing to do:
- m_reBar.GetReBarCtrl().ShowBand(0, FALSE);
- m_reBar.GetReBarCtrl().ShowBand(0, TRUE);
- }
- // This is required in order to make the LButtonDblClk() work!
- void CP4PaneView::LButtonClk()
- {
- SetFocus();
- }
- void CP4PaneView::LButtonDblClk()
- {
- // by default, do nothing
- }
- LRESULT CP4PaneView::OnFindPattern(WPARAM wParam, LPARAM lParam)
- {
- CP4ListCtrl * pList = DYNAMIC_DOWNCAST(CP4ListCtrl, GetContentWnd());
- ASSERT(pList);
- if(pList)
- return pList->OnFindPattern(wParam, lParam);
- return Default();
- }
- IMPLEMENT_DYNCREATE(CCaptionTextControl, CButton)
- BEGIN_MESSAGE_MAP(CCaptionTextControl, CButton)
- ON_WM_CTLCOLOR_REFLECT()
- END_MESSAGE_MAP()
- HBRUSH CCaptionTextControl::CtlColor(CDC* pDC, UINT /*nCtlColor*/)
- {
- // we don't want any background drawn; we're supposed to be transparent
- pDC->SetBkMode(TRANSPARENT);
- return (HBRUSH)GetStockObject(NULL_BRUSH);
- }
- void CCaptionTextControl::DrawItem(LPDRAWITEMSTRUCT di)
- {
- // Just draw the text. If it's too long, it will be shortened, since
- // we're using the DT_END_ELLIPSIS style. This also means the string
- // passed to DrawText may be modified, so we use a temp copy.
- CDC dc;
- dc.Attach(di->hDC);
- const int maxCaption = 256;
- TCHAR txt[maxCaption];
- GetWindowText(txt,maxCaption);
- txt[maxCaption-1] = 0;
- TCHAR mtxt[maxCaption];
- lstrcpy(mtxt,txt);
- dc.DrawText(mtxt, lstrlen(mtxt), &di->rcItem, DT_END_ELLIPSIS | DT_SINGLELINE|DT_VCENTER | DT_MODIFYSTRING);
- m_textTruncated = lstrcmp(mtxt,txt) != 0;
- dc.Detach();
- }
- int CCaptionTextControl::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
- {
- // CWnd implementation won't do us any good, so we have to handle
- // this.
- // watch out! sometimes get called with null pointer
- if(pTI == 0)
- return -1;
- // don't want to show tooltip if nothing is hidden
- // the tooltip is only there to show truncated text
- if(!m_textTruncated)
- return -1;
- // we want to show a tooltip, so set up for the normal callback
- pTI->hwnd = GetParent()->GetParent()->m_hWnd; // our parent
- pTI->uId = (UINT_PTR)m_hWnd; // us
- pTI->uFlags |= TTF_IDISHWND; // uId is HWND, not ID
- pTI->lpszText = LPSTR_TEXTCALLBACK;
- return 1;
- }
- DROPEFFECT CP4OleDropTarget::OnDragScroll(CWnd* pWnd, DWORD dwKeyState,
- CPoint point)
- {
- // We need special handling of autoscrolling because we want
- // it to behave as though the CP4PaneView's content window is
- // doing the autoscroll. Without this, it looks like you are
- // dragging over the caption to autoscroll the content.
- // This code is only slightly modified from the base implementation,
- // as needed to get the correct window's client rect for determining
- // the autoscroll inset region. Also, code for synchronized
- // scrolling of splitters has been stripped out.
- ASSERT_VALID(this);
- ASSERT_VALID(pWnd);
- // if it's not a CP4PaneView, just use the default handler
- CP4PaneView * pView = DYNAMIC_DOWNCAST(CP4PaneView,pWnd);
- if(!pView)
- return COleDropTarget::OnDragScroll(pWnd, dwKeyState, point);
- DROPEFFECT dropEffect = pView->OnDragScroll(dwKeyState, point);
- // DROPEFFECT_SCROLL means do the default
- if (dropEffect != DROPEFFECT_SCROLL)
- return dropEffect;
- // get client rectangle of destination window
- CRect rectClient;
- pView->GetContentWnd()->GetClientRect(&rectClient);
- pView->GetContentWnd()->MapWindowPoints(pView, &rectClient);
- CRect rect = rectClient;
- // hit-test against inset region
- UINT nTimerID = 0xffff;
- rect.InflateRect(-nScrollInset, -nScrollInset);
- if (rectClient.PtInRect(point) && !rect.PtInRect(point))
- {
- // determine which way to scroll along both X & Y axis
- if (point.x < rect.left)
- nTimerID = MAKEWORD(SB_LINEUP, HIBYTE(nTimerID));
- else if (point.x >= rect.right)
- nTimerID = MAKEWORD(SB_LINEDOWN, HIBYTE(nTimerID));
- if (point.y < rect.top)
- nTimerID = MAKEWORD(LOBYTE(nTimerID), SB_LINEUP);
- else if (point.y >= rect.bottom)
- nTimerID = MAKEWORD(LOBYTE(nTimerID), SB_LINEDOWN);
- ASSERT(nTimerID != 0xffff);
- // we don't do synchronized splitter scrolling, so this part is
- // somewhat simplified
- BOOL bEnableScroll = pView->OnScroll(nTimerID, 0, FALSE);
- if (!bEnableScroll)
- nTimerID = 0xffff;
- }
- if (nTimerID == 0xffff)
- {
- if (m_nTimerID != 0xffff)
- {
- // send fake OnDragEnter when transition from scroll->normal
- COleDataObject dataObject;
- dataObject.Attach(m_lpDataObject, FALSE);
- OnDragEnter(pWnd, &dataObject, dwKeyState, point);
- m_nTimerID = 0xffff;
- }
- return DROPEFFECT_NONE;
- }
- // save tick count when timer ID changes
- DWORD dwTick = GetTickCount();
- if (nTimerID != m_nTimerID)
- {
- m_dwLastTick = dwTick;
- m_nScrollDelay = nScrollDelay;
- }
- // scroll if necessary
- if (dwTick - m_dwLastTick > m_nScrollDelay)
- {
- pView->OnScroll(nTimerID, 0, TRUE);
- m_dwLastTick = dwTick;
- m_nScrollDelay = nScrollInterval;
- }
- if (m_nTimerID == 0xffff)
- {
- // send fake OnDragLeave when transitioning from normal->scroll
- OnDragLeave(pWnd);
- }
- m_nTimerID = nTimerID;
- // check for force link
- if ((dwKeyState & (MK_CONTROL|MK_SHIFT)) == (MK_CONTROL|MK_SHIFT))
- dropEffect = DROPEFFECT_SCROLL|DROPEFFECT_LINK;
- // check for force copy
- else if ((dwKeyState & MK_CONTROL) == MK_CONTROL)
- dropEffect = DROPEFFECT_SCROLL|DROPEFFECT_COPY;
- // check for force move
- else if ((dwKeyState & MK_ALT) == MK_ALT ||
- (dwKeyState & MK_SHIFT) == MK_SHIFT)
- dropEffect = DROPEFFECT_SCROLL|DROPEFFECT_MOVE;
- // default -- recommended action is move
- else
- dropEffect = DROPEFFECT_SCROLL|DROPEFFECT_MOVE;
- return dropEffect;
- }
- void CP4PaneView::OnSysColorChange()
- {
- CView::OnSysColorChange();
- m_toolBar.GetToolBarCtrl().SetImageList(
- TheApp()->GetToolBarImageList());
- m_toolBar.GetToolBarCtrl().SetDisabledImageList(
- TheApp()->GetToolBarImageList()->GetDisabled());
- CP4ListCtrl * pList = DYNAMIC_DOWNCAST(CP4ListCtrl, GetContentWnd());
- if(pList)
- pList->SetImageList(TheApp()->GetViewImageList(), LVSIL_SMALL);
- CMultiSelTreeCtrl * pTree = DYNAMIC_DOWNCAST(CMultiSelTreeCtrl, GetContentWnd());
- if(pTree)
- pTree->SetImageList(TheApp()->GetViewImageList(), TVSIL_NORMAL);
- }
- LRESULT CP4PaneView::OnActivateModeless(WPARAM wParam, LPARAM lParam)
- {
- CP4ListCtrl * pList = DYNAMIC_DOWNCAST(CP4ListCtrl, GetContentWnd());
- if(pList)
- pList->SendMessage(WM_ACTIVATEMODELESS, WA_ACTIVE, NULL);
- else
- {
- CMultiSelTreeCtrl * pTree = DYNAMIC_DOWNCAST(CMultiSelTreeCtrl, GetContentWnd());
- if(pTree)
- pTree->SendMessage(WM_ACTIVATEMODELESS, WA_ACTIVE, NULL);
- }
- return 0;
- }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 19924 | YourUncleBob |
Populate -o //guest/perforce_software/p4win/... //guest/YourUncleBob/p4win/..... |
9 years ago | |
//guest/perforce_software/p4win/main/gui/P4PaneView.cpp | |||||
#1 | 16169 | perforce_software | Move files to follow new path scheme for branches. | 9 years ago | |
//guest/perforce_software/p4win/gui/P4PaneView.cpp | |||||
#1 | 8562 | Matt Attaway | These feet never stop running. Initial commit of the P4Win source code. To the be...st of our knowledge this compiles and runs using the 2013.3 P4 API and VS 2010. Expect a few changes as we refine the build process. Please post any build issues to the forums. « |
11 years ago |